IdentityServer4 指定角色授权(Authorize(Roles="admin"))

简介:

1. 业务场景

IdentityServer4 授权配置Client中的AllowedScopes,设置的是具体的 API 站点名字,也就是使用方设置的ApiName,示例代码:

//授权中心配置
new Client
{
    ClientId = "client_id_1",
    AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
    AllowOfflineAccess = true,
    AccessTokenLifetime = 3600 * 6, //6小时
    SlidingRefreshTokenLifetime = 1296000, //15天
    ClientSecrets =
    {
        new Secret("secret".Sha256())
    },
    AllowedScopes = 
    {
        "api_name1"
    },
}

//API 服务配置
app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
{
    Authority = $"http://localhost:5000",
    ApiName = "api_name1",
    RequireHttpsMetadata = false
});

上面两个api_name1配置要一致,问题来了,因为授权中心的scope配置是整个 API 服务,如果我们存在多个Client配置,比如一个前台和后台,然后都需要访问api_name1,就会出现一些问题。

比如,api_name1服务中的一个接口服务配置代码:

[Authorize()]
[Route("api/values")]
[HttpGet]
public IActionResult Get()
{
    return Ok();
}

Authorize()的配置,说明api/values接口需要授权后访问,如果授权中心配置了两个Client(前台和后台),并且scope都包含了api_name1,现在就会出现两种情况:

  1. 前台Client和后台Client,都需要授权后访问api/values接口:没有问题。
  2. 前台Client不需要授权后访问,后台Client需要授权后访问:有问题,前台Client没办法访问了,因为api/values接口设置了Authorize()

其实,说明白些,就是该如何让 API 服务指定Client授权访问?比如:[Authorize(ClientId = 'client_id_1')]

2. 解决方案

没有[Authorize(ClientId = 'client_id_1')]这种解决方式,不过可以使用[Authorize(Roles = 'admin')]

授权中心的ResourceOwnerPasswordValidator代码,修改如下:

public class ResourceOwnerPasswordValidator : IResourceOwnerPasswordValidator
{
    private readonly IUserService _userService;

    public ResourceOwnerPasswordValidator(IUserService userService)
    {
        _userService = userService;
    }

    public async Task ValidateAsync(ResourceOwnerPasswordValidationContext context)
    {
        var user = await _userService.Login(context.UserName, context.Password);
        if (user != null)
        {
            var claims = new List<Claim>() { new Claim("role", "admin") }; //根据 user 对象,设置不同的 role
            context.Result = new GrantValidationResult(user.UserId.ToString(), OidcConstants.AuthenticationMethods.Password, claims);
        }
    }
}

授权中心的startup配置,修改如下

var builder = services.AddIdentityServer();
builder.AddTemporarySigningCredential()
        //.AddInMemoryIdentityResources(Config.GetIdentityResources())
        .AddInMemoryApiResources(new List<ApiResource>
        {
            new ApiResource("api_name1", "api1"){ UserClaims = new List<string> {"role"}}, //增加 role claim
            new ApiResource("api_name2", "api2"){ UserClaims = new List<string> {"role"}}
        })
        .AddInMemoryClients(Config.GetClients());

API 服务接口,只需要配置如下:

[Authorize()]
[Route("api/values")]
[HttpGet]
public IActionResult Get()
{
    return Ok();
}

[Authorize(Roles = "admin")]
[Route("api/values2")]
[HttpGet]
public IActionResult Get2()
{
    return Ok();
}

[Authorize(Roles = "admin,normal")]
[Route("api/values3")]
[HttpGet]
public IActionResult Get3()
{
    return Ok();
}

需要注意的是,api/values接口虽然没有设置具体的Roles,但每个Role都可以访问。





本文转自田园里的蟋蟀博客园博客,原文链接:http://www.cnblogs.com/xishuai/p/identityserver4-apiresource-userclaim-role-authorize.html,如需转载请自行联系原作者

相关文章
|
Java Spring
5-SpringSecurity:RBAC及方法授权
5-SpringSecurity:RBAC及方法授权
301 0
5-SpringSecurity:RBAC及方法授权
|
1月前
|
SQL 开发框架 关系型数据库
flea-auth使用之角色权限设计初识
本篇 Huazie 介绍 Flea框架下的角色权限设计
52 3
flea-auth使用之角色权限设计初识
|
4月前
|
Kubernetes API 容器
|
4月前
|
小程序 中间件 PHP
thinkphp5 Auth 权限管理(2)
这些代码按照正确的方式,放到你的项目中,auth权限管理应该就好用了。如果你的项目支持中间件,上边这部分代码直接放到中间件中就可以了。 我就是这样。
26 0
|
4月前
|
SQL PHP 数据安全/隐私保护
thinkphp5 Auth 权限管理(1)
<?php // +---------------------------------------------------------------------- // | ThinkPHP [ WE CAN DO IT JUST THINK IT ] // +---------------------------------------------------------------------- // | Copyright (c) 2011 http://thinkphp.cn All rights reserved. // +-----------------------
26 0
thinkphp5 Auth 权限管理(1)
|
5月前
|
存储 安全 数据安全/隐私保护
AWS 登录页面上 Root user 和 IAM user 的区别
AWS 登录页面上 Root user 和 IAM user 的区别
51 0
|
安全 Java 数据库
SpringSecurity权限命名ROLE_问题
SpringSecurity权限命名ROLE_问题
184 0
SpringSecurity权限命名ROLE_问题
|
存储 数据库
Confluence 6 数据库表-授权(Authentication)
下面的表格对用户授权有关的信息进行存储,这部分是通过嵌入到 Confluence 中的  Atlassian Crowd 框架实现的。
866 0
|
测试技术 数据安全/隐私保护