Open NikiforovAll opened 6 months ago
Is there a way, even not official from the library, to do that? I'm building a mvc app and I really want to use this keycloak resource. I've tryied on some ways, but didn't work.
I used the source directly, trying to put the tokens on cookies and recover, but no success.
Hi @luylucas10 , it should be possible. The only issue is to find a valid token for exchange. Have you tried exchaing id_token?
EDIT: Nop, It doesn't work, I've tested more now and have a problem to check permission because ideed it needs the user token, not just api access.
I could find a way.
I put "DisableHeaderPropagation": true
in the keycloak section in appsettings.cs, configuring the Program.cs like this:
builder
.Services
.AddAuthorization()
.AddKeycloakAuthorization()
.AddAuthorizationServer(builder.Configuration)
.ConfigureHttpClient(async (provider, client) =>
{
var tokenResponse = await client.RequestTokenAsync(new TokenRequest()
{
Address = builder.Configuration["Keycloak:auth-server-url"]+ "realms/" + builder.Configuration["Keycloak:realm"] + "/protocol/openid-connect/token",
GrantType = "client_credentials",
ClientId = builder.Configuration["Keycloak:resource"],
ClientSecret = builder.Configuration["Keycloak:credentials:secret"],
});
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(tokenResponse.TokenType, tokenResponse.AccessToken);
});
// Add services to the container.
builder.Services.AddControllersWithViews(a => a.AddProtectedResources());
I think that isn't the best way, but works. I'd try to use Duende Token Management but had problems with DI. Now in the action I can use [ProtectedResource("resource", "scope")]
in the MVC controllers.
If you could provide a better solution I'll really appreciate that. I can commit this example, I've created a new project at samples directory of the repo.---
Finally I have a solution.
This was the reference that I used: https://github.com/mderriey/aspnet-core-token-renewal/blob/master/src/MvcClient/Startup.cs
We still need the "DisableHeaderPropagation": true
in the appsettings and our program.cs like this:
builder
.Services
.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddKeycloakWebApp(builder.Configuration.GetSection(KeycloakAuthenticationOptions.Section),
configureOpenIdConnectOptions: options =>
{
options.SaveTokens = true;
options.ResponseType = OpenIdConnectResponseType.Code;
options.GetClaimsFromUserInfoEndpoint = true;
options.MapInboundClaims = false;
options.TokenValidationParameters.NameClaimType = JwtRegisteredClaimNames.Name;
options.TokenValidationParameters.RoleClaimType = ClaimTypes.Role;
options.Events = new OpenIdConnectEvents
{
OnSignedOutCallbackRedirect = context =>
{
context.Response.Redirect("/");
context.HandleResponse();
return Task.CompletedTask;
},
// guess this is the needed configurationn
OnTokenResponseReceived = context =>
{
var identity = context?.Principal?.Identity as ClaimsIdentity;
identity?.AddClaims(new[]
{
new Claim("access_token", context.TokenEndpointResponse.AccessToken),
new Claim("id_token", context.TokenEndpointResponse.IdToken)
});
// makes cookie and token with same expiration
context.Properties.IsPersistent = true;
context.Properties.ExpiresUtc = new JwtSecurityToken(context.TokenEndpointResponse.AccessToken).ValidTo;
return Task.CompletedTask;
}
};
});
builder
.Services
.AddAuthorization()
.AddKeycloakAuthorization()
.AddAuthorizationServer(builder.Configuration)
.ConfigureHttpClient(async (provider, client) =>
{
// get the token from user cookie and put in the header
var ctx = provider?.GetService<IHttpContextAccessor>()?.HttpContext;
var header = new AuthenticationHeaderValue("Bearer", await ctx?.GetTokenAsync("access_token"));
client.DefaultRequestHeaders.Authorization = header;
});
Now I have the [ProtectedResource]
working. Thank you for working on this integration for dotnet, I'll contribute, but for now, I have to speed up my personal project.
Awesome, I'm looking forward to your contribution. Looks good to me!
Currently, header propagation middleware assumes the presence of an access token in a header. This is not true for cookie-based applications