IdentityServer4 指定角色授权(Authorize(Roles="admin"))
2017-06-01 23:05
309 查看
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 指定角色授权(Authorize(Roles=&quot;admin&quot;))
- 让"指定的 MSProjectServerRole 帐户不属于 MSProjectServerRole 角色"去死吧
- Oracle中管理用户(创建用户,用户加锁,用户解锁,修改用户密码,授权登录权限,撤销登录权限,授权连接权限,conn命令,创建角色,并为角色赋权限,将角色赋给指定用户)
- 如何理解Oracle中"通过角色授权"需要用户重新登陆
- ORA-01932: ADMIN 选项未授权给角色 'CONNECT'
- [IBM][CLI Driver][DB2/NT] SQL1101N 不能以指定的授权标识和密码访问节点 "" 上的远程数据库 "LBZM"。 SQLSTATE=08004
- 解决Discuz!NT"Code: 100, Message: 指定..."问题
- Sql 语句把重复的记录放到指定列中,用","号分隔
- Asp.net中基于Forms验证的角色验证授权
- 【转】Oracle用户、授权、角色管理
- 附加数据库出现"所指定的文件不是有效的SQL Server数据库文件"
- "由于没有远程桌面授权服务器可以提供许可证..."不能远程桌面解决方法
- Asp.net中基于Forms验证的角色验证授权
- html input="file" 浏览时只显示指定文件类型 xls、xlsx、csv
- Oracle新建用户、角色,授权,建表空间的sql语句
- Blend "无法启动”http://localhost:xxxx/Default.html“出现以下错误System.ComponentModel.Win32Exception(0x80004005):系统找不到指定文件
- 关于无法加载DLL"***.dll":找不到指定的模块(异常来自HRESULT:0x8007007E)问题的解决办法
- ASP.NET2.0 - 授权Authorization(2) –使用角色管理网站
- Error Domain=NSCocoaErrorDomain Code=3000 "未找到应用程序的“aps-environment”的授权字符串" UserInfo={NSLocalizedDes
- 已经为元素 "web-app" 指定属性 "xmlns"