正确设置IdentityServer4 Cookie以进行登录,使用JWT令牌进行API授权

时间:2018-05-10 01:02:45

标签: asp.net-core authorization jwt identityserver4

我们有一个应用程序使用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
        }

};

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

的WebAPI

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

        .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时,我收到以下错误:

  

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

事实上,当我使用jwt.io解码令牌时,aud设置为http://localhost:50059/resources,而ClientID显示为新字段'client_id': '<ClientID>'

到目前为止我发现,aud始终设置为<idp>/resources来访问令牌,并且API访问权限是使用令牌内的范围声明来处理的。但是,我不明白如何正确设置它。

有人知道问题出在哪里以及如何解决问题?我将不胜感激。

1 个答案:

答案 0 :(得分:4)

事实证明,解决方案非常简单。可疑,它与范围有关。我试图解决这个问题,但它一直在说&#34;无效的范围&#34; ...因为我从未创建过API资源,呃。

  1. 在IDP服务器中创建新的API资源 new ApiResource("api-name", "API Name")
  2. 将新API资源作为AllowedScope添加到客户端 client.AllowedScopes.Add("api-name")
  3. 在OpenIdConnect身份验证中询问范围 options.Scopes.Add("api-name")
  4. 将受众(或使用IdentityServer身份验证处理程序时为ApiName)设置为API资源 options.Audience = "api-name" 要么 options.ApiName = "api-name"
  5. 有了这个,我现在可以使用访问令牌来访问我的API。