您的位置:首页 > 其它

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

2017-06-24 08:15 375 查看

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
,现在就会出现两种情况:

前台
Client
和后台
Client
,都需要授权后访问
api/values
接口:没有问题。

前台
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
都可以访问。

相关文章:

IdentityServer4(OAuth2.0服务)折腾笔记

IdentityServer4 实现 OpenID Connect 和 OAuth 2.0

IdentityServer4 使用OpenID Connect添加用户身份验证

IdentityServer4 ASP.NET Core的OpenID Connect OAuth 2.0框架学习保护API

原文地址:http://www.cnblogs.com/xishuai/p/identityserver4-apiresource-userclaim-role-authorize.html

.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐