IdentityServer4 基于角色的授权正确使用

时间:2021-04-17 18:23:40

标签: c# identityserver4 openid-connect roles claims

我目前正在开发一个 .net5.0 IdentityServer4 应用程序。

我想使用基于角色的授权,不幸的是它似乎无法正常工作。

当我在控制器操作上使用 [Authorization] 属性时,我可以正确登录。

当我在控制器操作上使用 [Authorize(Roles = "admin")] 属性时,我被转发到访问被拒绝页面 (403)。

当我使用角色 admin 登录我的 TestUser 时,我被转发到我的客户端应用程序上的访问被拒绝页面。

我的应用程序结构如下:

  • IdentityServer4
  • OIDC 客户端(文应用、授权码 + PKCE)

IdentityServer4 配置如下所示:

public static IEnumerable<Client> GetClients()
{
    return new List<Client>
    {
        new Client
        {
            ClientId = "oidcClient",
            ClientName = "Example Client Application",
            ClientSecrets = new List<Secret> { new Secret("secret".Sha256()) },

            AllowedGrantTypes = GrantTypes.Code,
            RedirectUris = new List<string> { "https://localhost:xxxx/signin-oidc" },
            AllowedScopes = new List<string>
            {
                IdentityServerConstants.StandardScopes.OpenId,
                IdentityServerConstants.StandardScopes.Profile,
                IdentityServerConstants.StandardScopes.Email,
                "role"
            },

            RequirePkce = true,
            AllowPlainTextPkce = false
        }
    };

public static IEnumerable<IdentityResource> GetIdentityResources()
{
    return new[]
    {
        new IdentityResources.OpenId(),
        new IdentityResources.Profile(),
        new IdentityResources.Email(),
        new IdentityResource
        {
            Name = "role",
            UserClaims = new List<string> { "role" }
        }
    };
}

public static List<TestUser> GetUsers()
{
    return new List<TestUser> {
        new TestUser {
            SubjectId = "123ABC",
            Username = "admin",
            Password = "password",
            Claims = new List<Claim> {
                new Claim(ClaimTypes.Email, "admin@test.com"),
                new Claim(ClaimTypes.Role, "admin")
            }
        }
    };
}

我的客户端应用上的 Oidc 连接配置如下所示:

services.AddAuthentication(options => 
{
    options.DefaultScheme = "cookie";
    options.DefaultChallengeScheme = "oidc";
})
.AddCookie("cookie")
.AddOpenIdConnect("oidc", options => 
{
    options.Authority = "https://localhost:5000";
    options.ClientId = "oidcClient";
    options.ClientSecret = "secret";

    options.ResponseType = "code";
    options.UsePkce = true;
    options.ResponseMode = "query";

    // Edit 1
    options.TokenValidationParameters = new TokenValidationParameters
    {
       NameClaimType = ClaimTypes.Name,
       RoleClaimType = ClaimTypes.Role
    };

    options.SaveTokens = true;
});

我的控制器操作非常简单 - 只有角色没有策略 - 看起来像这样:

[Authorize(Roles = "admin")] // Roles does not work
//[Authorize] works fine
public IActionResult Home()
{
    return View();
}

感觉访问令牌没有传递给我的客户端 - 只有身份令牌......

无论如何,当我调试用户声称的操作时,如下所示: enter image description here

我使用 IdentityServer4 TestUser 并且我还没有 IProfileService 实现。有必要吗?

你知道如何解决这个问题吗?

如何在我的应用程序中正确使用角色声明?

1 个答案:

答案 0 :(得分:1)

IdentityServer/OpenIDConnect 和 Microsoft 对名称声明的名称有不同的看法。所以你需要告诉你的应用你的角色和名称声明被称为什么。

像这样:

}).AddOpenIdConnect(options =>
{
    ...
    
    options.TokenValidationParameters = new TokenValidationParameters
    {
        NameClaimType = JwtClaimTypes.Name,
        RoleClaimType = JwtClaimTypes.Role,
    };

});
相关问题