Search code examples
asp.net-core-webapiidentityserver4rolespolicy

How to add/check policy and role .net core API securing with Identityserver4


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");
        }
  1. Is it possible access identity scope in .Net Core API? if yes, How to do?
  2. 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 ?
  3. 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?

Solution

  • 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