正确设置 IdentityServer4 Cookie 用于登录,JWT 令牌用于 API 授权

Posted

技术标签:

【中文标题】正确设置 IdentityServer4 Cookie 用于登录,JWT 令牌用于 API 授权【英文标题】:Correct way to setup IdentityServer4 Cookies for login, JWT token for API authorization 【发布时间】:2018-10-20 04:51:49 【问题描述】:

我们有一个应用程序使用 IdentityServer4 cookie 授权方案进行用户登录,如下所示:

services.AddAuthentication(options =>
        
            options.DefaultAuthenticateScheme = "Cookies";
            options.DefaultChallengeScheme = "oidc";
        )
        .AddCookie("Cookies")
        .AddOpenIdConnect("oidc", options =>
        
            options.SignInScheme = "Cookies";
            options.Authority = <local IDP server with IdentityServer4>;
            options.ClientId = <ClientId>;
            options.ClientSecret = <secret>
            options.ResponseType = "code id_token";
            options.SaveTokens = true;
            options.GetClaimsFromUserInfoEndpoint = true;
            options.Scope.Add("openid");
            options.Scope.Add("profile");
            options.Scope.Add("offline_access");
        )

IDP 上的客户端如下所示:

new Client

    ClientId = <ClientID>,
    ClientName = <ClientName>,
    AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,
    RequireConsent = true,
    ClientSecrets =  new Secret(<secret>.Sha256()) ,
    AllowOfflineAccess = true,
    RedirectUris =  "http://" + ip + "/signin-oidc" ,
    PostLogoutRedirectUris =  "http://" + ip + "/signout-callback-oidc" ,
    AllowedScopes = 
            IdentityServerConstants.StandardScopes.OpenId,
            IdentityServerConstants.StandardScopes.Profile
        
;

我们还有一个 WebAPI 位于 /api/...

目标是向 API 添加 JWT Bearer Token 授权。为此,我添加了以下代码:

        .AddJwtBearer(jwtOptions =>
        
            jwtOptions.Authority = <local IDP server with IdentityServer4>;
            jwtOptions.Audience = <ClientID>
            jwtOptions.SaveToken = true;
        )

API 受到保护

[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]

登录后,我得到了令牌

await HttpContext.GetTokenAsync("access_token");

但是,当我尝试使用该令牌访问 API 时,我收到以下错误:

AuthenticationFailed:IDX10214:观众验证失败。观众:'http://localhost:50059/resources'。不匹配:validationParameters.ValidAudience:ClientID 或 validationParameters.ValidAudiences:'null'。

确实,当我使用 jwt.io 解码令牌时,aud 设置为 http://localhost:50059/resources,而 ClientID 显示为一个新字段 'client_id': '&lt;ClientID&gt;'

到目前为止,我的发现表明,对于访问令牌,aud 始终设置为 &lt;idp&gt;/resources,并且 API 访问由令牌内的范围声明处理。但是,我不明白如何正确设置。

有人知道问题出在哪里以及如何解决吗?

【问题讨论】:

【参考方案1】:

结果证明解决方案非常简单。正如怀疑的那样,它与范围有关。我之前试图解决这个问题,但它一直说“无效范围”......因为我从未创建过 API 资源,呵呵。

    在您的 IDP 服务器中创建新的 API 资源 new ApiResource("api-name", "API Name") 将新的 API 资源作为 AllowedScope 添加到客户端 client.AllowedScopes.Add("api-name") 在 OpenIdConnect 身份验证中询问范围 options.Scopes.Add("api-name") 将 Audience(或 ApiName,如果使用 IdentityServer 身份验证处理程序)设置为 API 资源 options.Audience = "api-name" 要么 options.ApiName = "api-name"

现在我可以使用访问令牌来访问我的 API。

【讨论】:

以上是关于正确设置 IdentityServer4 Cookie 用于登录,JWT 令牌用于 API 授权的主要内容,如果未能解决你的问题,请参考以下文章

.net core 5.0 with IdentityServer4 返回 api 方法 404

IdentityServer4:如何为 Google 用户设置角色?

如何将 IdentityServer4 设置为外部身份提供者

IdentityServer4 访问令牌生命周期

cook的特性

授权认证(IdentityServer4)