IdentityServer 4 - 缺少用户角色

时间:2018-03-14 20:12:08

标签: asp.net-core-2.0 identityserver4

在我的客户端中,我进行了以下设置。

services.AddAuthentication(options =>
    {
        options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
        //options.DefaultSignInScheme = "Cookies",
    })
    .AddCookie()
    .AddOpenIdConnect(options =>
    {
        options.Authority = "...";
        options.ClientId = "...";
        options.SaveTokens = true;
        options.ClientSecret = "secret";
        options.SignInScheme = "Cookies";
        options.Scope.Add("openid");
        options.Scope.Add("profile");
        options.Scope.Add("roles");
        options.ResponseType = "code id_token";
        options.GetClaimsFromUserInfoEndpoint = true;
        options.Events = new OpenIdConnectEvents()
        {
            OnTokenValidated = tokenValidatedContext =>
            {
                var identity = tokenValidatedContext.Principal.Identity
                    as ClaimsIdentity;

                var targetClaims = identity.Claims.Where(z =>
                    new[] {"sub"}.Contains(z.Type));

                var newClaimsIdentity = new ClaimsIdentity(
                    targetClaims,
                    identity.AuthenticationType,
                    "given_name",
                    "role");

                tokenValidatedContext.Principal =
                    new ClaimsPrincipal(newClaimsIdentity);

                return Task.CompletedTask;
            },
            OnUserInformationReceived = userInformationReceivedContext =>
            {
                return Task.FromResult(0);
            }
        };
    });

我在IdentityServer级别的客户端定义如下。

new Client()
{
    ClientName = "My App",
    ClientId = "mymagicapp",
    AllowedGrantTypes = GrantTypes.Hybrid,
    RedirectUris = new List<string>()
    {
        "https://..."
    },
    AllowedScopes =
    {
        IdentityServerConstants.StandardScopes.OpenId,
        IdentityServerConstants.StandardScopes.Profile,
        "roles"
    },
    ClientSecrets = { new Secret("secret".Sha256()) },
    PostLogoutRedirectUris =
    {
        "https://..."
    }
}

新的&#34;角色&#34;范围按以下方式添加。

public static IEnumerable<IdentityResource> GetIdentityResources()
{
    return new List<IdentityResource>()
    {
        new IdentityResources.OpenId(),
        new IdentityResources.Profile(),
        new IdentityResource("roles", "Your role(s)", new List<string>(){"role"})
    };
}

用户定义如下。

new TestUser()
{
    SubjectId = "abcdef",
    Username = "Jane",
    Password = "password",
    Claims = new List<Claim>()
    {
        new Claim("given_name", "Jane"),
        new Claim("family_name", "Doe"),
        new Claim("role", "FreeUser")
    }
}

登录到我的MVC客户端后,在Controller中,User.Claims对象不包含role声明。

但是,在OnUserInformationReceived userInformationReceivedContext User对象确实包含role声明。

我错过了什么?

2 个答案:

答案 0 :(得分:1)

基于

解决方案是在options.ClaimActions.MapJsonKey("role", "role");

中添加.AddOpenIdConnect(options => ...)

从第二个链接:

  

2.0不再添加来自user-info端点的所有可能信息,导致主要的cookie膨胀导致登录问题。现在有一个名为ClaimActions的系统,您可以在其中选择要从用户信息文档到索赔要映射的元素。请参阅OpenIdConnectOptions.ClaimActions

答案 1 :(得分:0)

您想要的是在access_token中添加声明,并且您需要ApiResource

public static IEnumerable<ApiResource> GetApiResources()
{
    return new List<ApiResource>
    {
        new ApiResource("roles", "Your role(s)", new List<string>(){"role"})
    };
}

并将其添加到IdentityServer

services.AddIdentityServer()
        .AddInMemoryApiResources(GetApiResources())

您可以学习documents了解更多信息