Hi all,
I’ve got stuck for several days on calling a Web API which I secured with Keycloak, I’m new to all of this stuff so clearly I’m doing something wrong.
I set up a local Keycloak server, this is working, created a realm (QuestionEngine) and a client Fortitude. I created a simple WebApi project, in Startup I added:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(o =>
{
o.Authority = Configuration["Jwt:Authority"];
o.Audience = Configuration["Jwt:Audience"];
o.Events = new JwtBearerEvents()
{
OnAuthenticationFailed = c =>
{
c.NoResult();
c.Response.StatusCode = 500;
c.Response.ContentType = "text/plain";
return c.Response.WriteAsync("OnAuthenticationFailed, eception: " + c.Exception);
}
};
});
}
In appsettings.json I added:
“jwt”: {
“Athority”: “baseurl/auth/realms/QuestionEngine”,
“Audience”: “Fortitude”
},
Further in the controller I added a test method:
[Authorize]
[HttpGet]
[Route(“RetrieveForecast”)]
public string RetrieveForecast()
{
return “Cold”;
}
In my test console application I retrieve the access token:
const string url = “baseurl/auth/realms/QuestionEngine/protocol/openid-connect/token”;
var nvc = new List<KeyValuePair<string, string>>();
nvc.Add(new KeyValuePair<string, string>(“username”, “app-user”));
nvc.Add(new KeyValuePair<string, string>(“password”, “test”));
nvc.Add(new KeyValuePair<string, string>(“grant_type”, “password”));
nvc.Add(new KeyValuePair<string, string>(“client_id”, “Fortitude”));
nvc.Add(new KeyValuePair<string, string>(“client_secret”, “4611972e-33bc-4449-a553-668107352223”));
var client = new HttpClient();
var req = new HttpRequestMessage(HttpMethod.Post, url) { Content = new FormUrlEncodedContent(nvc) };
var res = await client.SendAsync(req);
if (res.StatusCode == HttpStatusCode.OK)
{
var apiResponse = await res.Content.ReadAsStringAsync();
var tokenResult = JsonConvert.DeserializeObject(apiResponse);
return tokenResult.access_token;
}
This also seems to work.
Now I want to call the test method in the Api, something like:
using var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(“Bearer”, userToken);
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(“application/json”));
using var response = await httpClient.GetAsync(“http://localhost:64091/weatherforecast/RetrieveForecast”);
When I leave the header I retrieve unauthorized what seems to be fine, with header I receive internal server error. Any idea what’s my mistaking?
Regards, Koert
PS: baseurl = http://localhost:8080, otherwise I couldn’t post as newby