问题
I'm using the IdentityServer4 "AspNetCoreAndApis" sample application found here
It has a token server and an MVC client application.
The identity server project has an external OIDC authentication provider set up using their demo server - https://demo.identityserver.io/
After hitting a protected endpoint in MvcClient
, being redirected to the local identity server, choosing and authenticating with the demo server, it reaches the ExternalController
callback of the local identity server. At this point I would like to issue additional claims to the user, and have them be available in MvcClient
.
There's code in the callback to addadditionalLocalClaims
and issue a cookie. I tried adding another claim:
var additionalLocalClaims = new List<Claim>();
additionalLocalClaims.Add(new Claim("TestKey", "TestValue"));
await HttpContext.SignInAsync(user.SubjectId, user.Username, provider, localSignInProps, additionalLocalClaims.ToArray());
But by the time the user arrives in the HomeController
of MvcClient
this claim is not there.
I think I don't properly understand which authentication scheme is being used where, and the function of the relevant cookies.
EDIT:
In response to the first comment below, I tried attaching a claim to a requested scope, but still no luck - this is the in memory resource store:
public static IEnumerable<ApiResource> Apis
{
get
{
var apiResource = new ApiResource("api1", "My API");
apiResource.UserClaims.Add("TestKey");
var resources = new List<ApiResource>
{
apiResource
};
return resources;
}
}
The MvcClient is both allowed the api1 scope, and requests it.
回答1:
Your client MVC could get the user's custom claims from ID token or UserInfo endpoint .
To add claims to ID token , you can set client's config :AlwaysIncludeUserClaimsInIdToken
. But involve all user claims in ID token is not recommended concern about the size of ID Token .
A better solution is making your client app get user's claims from UserInfo endpoint :
public class MyProfileService : IProfileService
{
public MyProfileService()
{ }
public Task GetProfileDataAsync(ProfileDataRequestContext context)
{
var claims = new List<Claim>()
{
new Claim("TestKey", "TestValue")
};
context.IssuedClaims.AddRange(claims);
return Task.CompletedTask;
}
public Task IsActiveAsync(IsActiveContext context)
{
// await base.IsActiveAsync(context);
return Task.CompletedTask;
}
}
Register in DI :
services.AddTransient<IProfileService, MyProfileService>();
The IProfileService
service could be used to add claims to ID Token, Access token and UserInfo endpoint . By default the custom claims won't involve in ID Token event using IProfileService
, the reason explained above - the ID token size . So you can make your client app get claims from UserInfo endpoint with OIDC middleware config :
options.Scope.Add("profile");
options.GetClaimsFromUserInfoEndpoint = true;
options.ClaimActions.MapJsonKey("TestKey", "TestKey");
Above codes will add OIDC profile
permission to get claims from endpoint , and send a request to connect/userinfo
endpoint with ID Token , and get claims and map claim whose name is TestKey
to your client's claim principle and save to cookie . Now you can get the claims with User.Claims
in MVC .
来源:https://stackoverflow.com/questions/59145054/how-to-add-additional-claims-for-mvc-client-with-identityserver4