Inject role when token is validated
lufo88ita opened this issue · 3 comments
Confirm you've already contributed to this project or that you sponsor it
- I confirm I'm a sponsor or a contributor
Version
5.7.0
Question
Hi again Kevin,
as a reminder:
My company sponsered you through the account SCP-srl, I'm a member of it.
https://github.com/orgs/SCP-srl/people
We have another problem with the same application which you help us to make work:
#2133
The authentication works like a charm ( :-) ), however we need to inject the roles. We won't (and cannot) use the roles in the authentication server, instead we retrieve them from a custom table of the application and inject their.
With the previous OIDC client we have an handler where we perform this injection. The code was like this:
Notifications = new OpenIdConnectAuthenticationNotifications
{
SecurityTokenValidated = async context =>
{
var identity = context .AuthenticationTicket.Identity;
var serviceRoles = DependencyResolver.Current.GetService(typeof(IRoleService)) as IRoleService;
var currentUserSub = identity .Claims.First(c => c.Type == "sub").Value;
var roles = ur.GetRoleUser(currentUserSub);
foreach (var r in roles)
{
identity .AddClaim(new Claim("role", r.Name));
}
context.AuthenticationTicket = new AuthenticationTicket(identity, context.AuthenticationTicket.Properties);
},
}
});
We try to use your EventHandler, but we failed to understand which event is the equivalent of the old one.
I wrote this scoped handler
public class AddCustomRoleHandler : IOpenIddictClientHandler<?>
{
public AddCustomRoleHandler() {
}
public ValueTask HandleAsync(HandleUserinfoResponseContext context)
{
var ruoliService = DependencyResolver.Current.GetService(typeof(IRoleService)) as IRoleService;
var roles = ruoliService.GetRoleUser(context.Principal.Claims.First(c => c.Type == Claims.Subject).Value);
context.Principal = new GenericPrincipal(context.Principal.Identity, roles.Select(r => r.Name).ToArray());
return default;
}
}
And added this
options.AddEventHandler<OpenIddictClientEvents.?>((builder) =>
{
builder.UseScopedHandler<AddCustomRoleHandler>();
});
In the client definition, but I do not know which event to attach.
Hey @lufo88ita,
The authentication works like a charm ( :-) ), however we need to inject the roles. We won't (and cannot) use the roles in the authentication server, instead we retrieve them from a custom table of the application and inject their.
You could use the events model for that but the best option is to do it directly in the callback action of your authentication controller, where you have access to all the claims extracted by OpenIddict and can add any other claim you need - typically based on the user identity - before it is stored in the authentication cookie:
Hi, thanks for the reply. I apply your suggest.
Just a quick question: do you know why the method User.isInRole() check on the claim with the name
"http://schemas.microsoft.com/ws/2008/06/identity/claims/role"
and not
"role"
?
Forgot it I found the reason. I use the wrong constant while build the ClaimsIdentity. 👎 I will fix it myself.
Thanks for the help.