HTTPClient call to KeyCloak secured WebApi

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