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

IdentityServer4 role based authorization correct use

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

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

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

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

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

我的应用程序结构如下所示:

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();
}

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

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

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

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

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

IdentityServer/OpenIDConnect 和微软对于名称声明应该叫什么有不同的看法。所以你需要告诉你的应用程序你的角色和名称声明是什么。

像这样:

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

});