I have a doubt on API securing with identity server4
IdentityResource
Name | Claims |
---|---|
Roles | role |
APIResource
Name | Scopes |
---|---|
testapi | api1 |
APIScopes
Name | Claims |
---|---|
api1 | address |
In Startup.cs
services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
.AddJwtBearer("Bearer", opt =>
{
opt.Audience = "testapi";
opt.Authority = "https://localhost:5001";
opt.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
{
ValidateAudience = true
};
});
//Policy "Apiscope" created
services.AddAuthorization(opt =>
{
opt.AddPolicy("Apiscope", policy =>
{
policy.RequireAuthenticatedUser();
policy.RequireClaim("Scope", "api1");
});
});
services.AddAuthorization(opt =>
{
opt.AddPolicy("AdminUsers", policy =>
{
policy.RequireAuthenticatedUser();
policy.RequireRole("admin");
});
});
In controller
[HttpPost]
[Authorize(Policy = "AdminUsers")]
public IActionResult GetAdminMessage()
{
return Ok("Hello Admin");
}
Is it possible access identity scope in .Net Core API? if yes, How to do?
The claims in the IdentityResources goes into the ID-Token. The content of the ID-Token is "converted" into the ClaimsPrincipal User object when you login in the client (AddOpenIDConnect). After that the ID-token is not used.
To get the role value, do I need to add in APIScopes of "api1" userclaims as "address,role" or can do it by above Q1 ?
APIScopes are on the API Side. API's receives Access-Tokens and it contains the user claism from the ApiSCopes and ApiResources. The claims in the access-token is converted into the user object in the API (using the AddJwtBearer) and you can use the AddPolicy system to authorize the user.
In Policy "AdminUser", I am checking role by adding "api1" (APIScopes) userclaims as "address,role" but I could not access GetAdminMessage(). How to achieve this?
ASP.NET Core and IdentityServer have different opinions on what the claim types (names) should be, so you need to tell AddJwtBearer what the real name is of your role claim, by using:
.AddJwtBearer(opt =>
{
...
opt.TokenValidationParameters.RoleClaimType = "roles";
opt.TokenValidationParameters.NameClaimType = "name";
You can also add this at the top of the ConfigureServicesmethod:
public void ConfigureServices(IServiceCollection services)
{
// By default, Microsoft has some legacy claim mapping that converts
// standard JWT claims into proprietary ones. This removes those mappings.
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
JwtSecurityTokenHandler.DefaultOutboundClaimTypeMap.Clear();
If that does not help ,you can also try add:
options.ClaimActions.MapUniqueJsonKey("role", "role");
To complement this answer, I wrote a blog post that goes into more detail about this topic: Troubleshooting JwtBearer authentication problems in ASP.NET Core and Debugging OpenID Connect claim problems in ASP.NET Core