【问题标题】:How to properly use claims with IdentityServer4?如何正确使用 IdentityServer4 的声明?
【发布时间】:2019-03-21 17:01:43
【问题描述】:

我正在尝试了解这是如何工作的,所以请多多包涵。 这是我的身份服务器配置:

    public static IEnumerable<ApiResource> GetApiResources(IConfiguration configuration)
    {
        return new []
        {
            new ApiResource
            {
                Name = "invoices.api",

                ApiSecrets =
                {
                    new Secret("invoices.api.secret".Sha256()),
                },

                Scopes =
                {
                    new Scope("invoices.api.scope"),
                },

                UserClaims =
                {
                    "custom_role",
                }
            }
        };
    }

    public static IEnumerable<Client> GetClients(IConfiguration configuration)
    {
        return new []
        {
            new Client
            {
                ClientId = "invoices.ui",
                RequireConsent = false,
                AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,
                AccessTokenType = AccessTokenType.Reference,

                AllowedCorsOrigins = configuration.GetSection("Redirect").Get<RedirectOptions>().AllowedCorsOrigins.ToList(),
                RedirectUris = configuration.GetSection("Redirect").Get<RedirectOptions>().RedirectUris.ToList(),
                PostLogoutRedirectUris = configuration.GetSection("Redirect").Get<RedirectOptions>().PostLogoutRedirectUris.ToList(),

                ClientSecrets =
                {
                    new Secret("invoices.ui.secret".Sha256())
                },

                AllowedScopes =
                {
                    IdentityServerConstants.StandardScopes.OpenId,
                    "invoices.api.scope",
                },
            }
        };
    }

    public static IEnumerable<TestUser> GetUsers(IConfiguration configuration)
    {
        return new []
        {
            new TestUser
            {
                SubjectId = "1",
                Username = "alice",
                Password = "123",
                Claims =
                {
                    new Claim("custom_role", "user"),
                },
            },
            new TestUser
            {
                SubjectId = "2",
                Username = "bob",
                Password = "123",
                Claims =
                {
                    new Claim("custom_role", "admin"),
                },
            }
        };
    }

    public static IEnumerable<IdentityResource> GetIdentityResources(IConfiguration configuration)
    {
        return new []
        {
            new IdentityResources.OpenId(),
        };
    }

这就是我的 MVC 客户端的设置方式:

    services.AddAuthentication(options =>
    {
        options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = "oidc";
    })
    .AddCookie(opts =>
    {
        //opts.ExpireTimeSpan = TimeSpan.FromSeconds(60);
    })
    .AddOpenIdConnect("oidc", opts =>
    {
        opts.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;

        opts.DisableTelemetry = true;

        opts.Authority = Configuration.GetValue<string>("IdentityServer");
        opts.RequireHttpsMetadata = false;

        opts.ClientId = "invoices.ui";
        opts.ClientSecret = "invoices.ui.secret";
        opts.ResponseType = "code id_token";

        opts.SaveTokens = true;
        opts.GetClaimsFromUserInfoEndpoint = true;

        opts.Scope.Clear();
        opts.Scope.Add("openid");
        opts.Scope.Add("invoices.api.scope");
    });

用户通过身份验证后,我试图查看它的声明,如下所示:

    @foreach (var claim in User.Claims)
    {
        <dt>@claim.Type</dt>
        <dd>@claim.Value</dd>
    }

但该列表不包含任何“custom_role”声明。 身份服务器日志显示客户端已从用户信息端点请求用户信息,但我的“custom_role”并未在那里传输,但它显示在身份服务器的日志中,该用户拥有它。

如何在我的 MVC 应用中访问我的自定义声明? 我需要从用户端点获取它们并用于授权。

【问题讨论】:

  • 谢谢。那是我当然也会使用的东西,但它并不能解决主要问题。声明不会从使用信息端点传输到客户端。日志显示未发出任何索赔。也许我需要使用某种范围或类似的东西以某种方式从客户那里专门请求它们?
  • 我明白了。在这种情况下,您可能需要自定义 Profile Service

标签: asp.net-core identityserver4


【解决方案1】:

如果您要求 访问令牌身份令牌(“代码 id_token”),Identity Server 将默认不包含用户声明。

解决方案是将AlwaysIncludeUserClaimsInIdToken 设置为true。见http://docs.identityserver.io/en/release/reference/client.html

为什么存在这个设置的解释在这里:https://leastprivilege.com/2016/12/14/optimizing-identity-tokens-for-size/

【讨论】:

  • 谢谢,但我已专门启用 GetClaimsFromUserInfoEndpoint 并在 MVC 中使用引用令牌,因此中间件会从端点请求声明,而不是从令牌中获取它们。或者我误解了它是如何工作的?
【解决方案2】:

似乎即使使用内置 ProfileService 实现,添加具有指定声明的身份资源也可以解决问题:

    public static IEnumerable<IdentityResource> GetIdentityResources(IConfiguration configuration)
    {
        return new []
        {
            new IdentityResources.OpenId(),
            new IdentityResource
            {
                Name = "roles.scope",
                UserClaims =
                {
                    "custom_role",
                }
            }
        };
    }

还将其添加为客户端的范围:

    AllowedScopes =
    {
        IdentityServerConstants.StandardScopes.OpenId,
        "invoices.api.scope",
        "roles.scope",
    },

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-15
    • 2020-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-07
    • 2018-04-03
    • 1970-01-01
    相关资源
    最近更新 更多