代码之家  ›  专栏  ›  技术社区  ›  gargaroff

为登录设置IdentityServer4 Cookie、为API授权设置JWT令牌的正确方法

  •  7
  • gargaroff  · 技术社区  · 7 年前

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

    目标是将JWT承载令牌授权添加到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。有效期:“null”。

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

    我目前发现的情况表明 MBaud 始终设置为 <idp>/resources 对于访问令牌,API访问是通过令牌内的范围声明来处理的。然而,我不知道如何正确设置。

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

    1 回复  |  直到 5 年前
        1
  •  5
  •   gargaroff    7 年前

    结果证明,解决方案非常简单。正如所怀疑的那样,这与示波器有关。我之前试图解决这个问题,但它一直在说“无效范围”。。。因为我从来没有创建过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. 将访问群体(或ApiName,如果使用IdentityServer身份验证处理程序)设置为API资源 options.Audience = "api-name" options.ApiName = "api-name"

    有了它,我现在可以使用访问令牌访问我的API。