簡體   English   中英

Identity Server 4 - MVC 客戶端的 OpenIdConnect 處理程序中缺少角色聲明

[英]Identity Server 4 - Role claims missing in OpenIdConnect handler in MVC client

我知道這個問題已經被報告了很多,並且有很多關於如何解決這個問題的文章。 我已經經歷了很多,但仍然無法解決這個問題。

我在 Identity Server 的OnSecurityTokenValidated回調中對Principal.Identity設置自定義聲明,如下所示:

public async Task SecurityTokenValidated(SecurityTokenValidatedContext context) {
    var identity = context.Principal.Identity as ClaimsIdentity;
    foreach(var claim in context.Principal.Claims.Where(x = >x.Type == "adGroupClaimType").ToList()) {
        var groupName = Configuration.GetSection("ClaimMappings").GetValue < string > ($ "Prefix_{claim.Value}");
        if (!string.IsNullOrWhiteSpace(groupName)) {
            identity.AddClaim(new Claim(ClaimTypes.Role, groupName));
        }

        identity.RemoveClaim(claim);
    }
}

以下是我在 Identity Server 中使用的配置:

public static IEnumerable < IdentityResource > IdentityResources = >new List < IdentityResource > {
    new IdentityResources.OpenId(),
    new IdentityResources.Profile(),
    new IdentityResource("roles", new[] {
        ClaimTypes.Role
    })
};

public static IEnumerable < ApiScope > ApiScopes = >new List < ApiScope > {
    new ApiScope("api", "API")
};

public static IEnumerable < Client > Clients = >new List < Client > {
    new Client {
        ClientId = "mvc-openid",
        ClientSecrets = {
            new Secret("secret".Sha256())
        },
        AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,
        RedirectUris = {
            "https://localhost:6001/signin-oidc"
        },
        AllowedScopes = new List < string > {
            IdentityServerConstants.StandardScopes.OpenId,
            IdentityServerConstants.StandardScopes.Profile,
            "api",
            "roles"
        },
        RequirePkce = false,
        AllowOfflineAccess = true,
        AllowAccessTokensViaBrowser = true
    }
};

有一個 MVC 客戶端使用 OpenIdConnect 連接到 Identity Server。 代碼如下:

public void ConfigureServices(IServiceCollection services) {
    services.AddMvc();
    JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
    JwtSecurityTokenHandler.DefaultMapInboundClaims = false;

    services.AddAuthentication(options = >{
        options.DefaultScheme = "Cookies";
        options.DefaultChallengeScheme = "oidc";
    }).AddCookie(options = >{
        options.ExpireTimeSpan = 15;
        options.SlidingExpiration = true;
        options.Cookie.SameSite = Microsoft.AspNetCore.Http.SameSiteMode.None;
    }).AddOpenIdConnect("oidc", options = >{
        options.Authority = "https://localhost:5001";
        options.ClientId = "mvc-openid";
        options.ClientSecret = "secret";
        options.ResponseType = "code id_token token";
        options.GetClaimsFromUserInfoEndpoint = true;
        options.SaveTokens = true;
        options.Scope.Add("api");
        options.Scope.Add("roles");
        options.Scope.Add("offline_access");
        options.Events.OnTokenValidated = OnTokenValidated;
        options.TokenValidationParameters = new TokenValidationParameters {
            NameClaimType = ClaimTypes.Name,
            RoleClaimType = ClaimTypes.Role
        };

        options.ClaimActions.MapUniqueJsonKey(ClaimTypes.Role, ClaimTypes.Role);
    });
}

private Task OnTokenValidated(TokenValidatedContext context) {
    var t = context.Principal.Claims;
    return Task.CompletedTask;
}

當我檢查OnTokenValidated中的聲明時,我可以看到我從 Identity Server 設置的所有角色聲明都丟失了。 有人可以告訴我哪里出錯了嗎? 我已經嘗試了在 Stack Overflow 線程上找到的關於這個問題的幾乎所有內容。 現在不知道下一步該做什么。

到目前為止,我也只找到了這個解決方案。

options.Events.OnUserInformationReceived = context =>
{
    var roleElement = context.User.RootElement.GetProperty("role");

    var claims = new List<Claim>();
    if (roleElement.ValueKind == System.Text.Json.JsonValueKind.Array)
    {
        foreach (var r in roleElement.EnumerateArray())
            claims.Add(new Claim(JwtClaimTypes.Role, r.GetString()));
    }
    else
    {
        claims.Add(new Claim(JwtClaimTypes.Role, roleElement.GetString()));
    }

    var id = context.Principal.Identity as ClaimsIdentity;
    id.AddClaims(claims);

    return Task.CompletedTask;
};

https://github.com/skoruba/IdentityServer4.Admin/issues/109

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM