IdentityServer4 QuckStart 授权与自定义Claims的问题

最近在折腾IdentityServer4,为了简单,直接使用了官方给的QuickStart示例项目作为基础进行搭建。有一说一,为了保护一个API,感觉花费的时间比写一个API还要多。

本文基于ASP.NET CORE 3.1, IdentityServer4 3.1.3。代码皆为关键代码,贴全了太多了。

好不容易跑起来了,最终的任务要落实到授权的工作上来。在API中使用Authorize用来限制用户的访问。

[Route("api/[controller]")]
[Authorize(Roles = "Administrator")]
[ApiController]
public class UserInfoController : ControllerBase
{
 /// <summary>
 /// 无参GET请求
 /// </summary>
 /// <returns></returns>
 [HttpGet()]
 [ProducesResponseType(typeof(ReturnData<IEnumerable<UserInfo>>), Status200OK)]
 public async Task<ActionResult> Get()
 {
 var info = new Info<UserInfo>();
 return Ok(new ReturnData<IEnumerable<UserInfo>>(await info.Get()));
 }

然而在使用的时候,虽然正确取得授权,但是却无法正常访问API,一直提示401没有授权错误。仔细检查,发现IdentityServer4返回的内容并没有返回role的JwtClaimTypes,没有它,Authorize无法正常工作。

{
 "nbf": 1587301921,
 "exp": 1587305521,
 "iss": "http://localhost:5000",
 "aud": "MonitoringSystemApi",
 "client_id": "webClient",
 "sub": "c6c18d4d-c28e-4de5-86dd-779121216204",
 "auth_time": 1587301921,
 "idp": "local",
 "scope": [
 "roles",
 "MonitoringSystemApi",
 "offline_access"
 ],
 "amr": [
 "pwd"
 ]
}

实现

查看Config.cs,IdentityServer4默认只返回两种IdentityResource:openid和profile。按照官方的说法,这个东西定义的内容会返回到用户的token。参考。那么就果断给它安排。

public static IEnumerable<IdentityResource> Ids =>
new List<IdentityResource>
{
 new IdentityResources.OpenId(),
 new IdentityResources.Profile(),
 new IdentityResource ("roles", new List<string> { JwtClaimTypes.Role }){ Required = true}
};

public static IEnumerable<Client> Clients =>
 new List<Client>
 {
 new Client
 {
  ClientId = "webClient",
  ClientSecrets = { new Secret("secret".Sha256()) },
  AllowOfflineAccess = true,
  AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
  // scopes that client has access to
  AllowedScopes = {
  "roles",

  "MonitoringSystemApi" }
 },

执行之前,需要确保数据库中的用户数据,已经包含role的Claim。

//添加用户代码
bob = new ApplicationUser
{
 UserName = "bob"
};
var result = userMgr.CreateAsync(bob, "Pass123$").Result;
if (!result.Succeeded)
{
 throw new Exception(result.Errors.First().Description);
}
result = userMgr.AddClaimsAsync(bob, new Claim[]{
new Claim(JwtClaimTypes.Role, "Administrator"),
new Claim(JwtClaimTypes.Name, "Bob Smith"),

运行程序,返回值依旧没有任何变化,很挫败,只能继续折腾。
研究通过实现IProfileService达到自定义Cliams。文章写的很详细,我这就不重复了,我实际试验过,可以成功。

但是文章末尾的注意,很重要。

“那么, 通过profileservice颁发的claims, 任意clients都能拿到”

说明这个优先级是非常高的,可以覆盖所有的行为,当然我们可以在IProfileService的实现上对权限进行进一步的设置,不过还是挺麻烦的。参考实现参考官方

作为懒人,必然不想再费劲去折腾权限的问题,那么是否有简单点的办法呢?

网上有一些问答说到了可以通过设置Scopes来达到目的。不过过于久远,IdentityServer4已经没有这个独立的类了,说是已经被ApiResource取代了。

直觉上这个东西应该是指示要保护的API的相关内容的,好像和这个没啥关系,不过也只能死马当活马医了。修改config.cs,最终如下内容:

public static IEnumerable<ApiResource> Apis =>
new List<ApiResource>
{
 new ApiResource("pls", new[]{ "role"}),
};

public static IEnumerable<Client> Clients =>
new List<Client>
{
new Client
{
 ClientId = "webClient",
 ClientSecrets = { new Secret("secret".Sha256()) },
 AllowOfflineAccess = true,
 AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
 // scopes that client has access to
 AllowedScopes = {
 "pls"
 }
},

返回结果如下:

{
 "nbf": 1587301799,
 "exp": 1587305399,
 "iss": "http://localhost:5000",
 "aud": "pls",
 "client_id": "webClient",
 "sub": "c6c18d4d-c28e-4de5-86dd-779121216204",
 "auth_time": 1587301799,
 "idp": "local",
 "role": "Administrator",
 "scope": [
 "pls",
 "offline_access"
 ],
 "amr": [
 "pwd"
 ]
}

终于看见心心念念的自定义Claim(role),可以去访问API了。

注意,在Client中也有个Claims,添加了role并且设置AlwaysSendClientClaimsAlwaysIncludeUserClaimsInIdToken之后,会在token中添加client_roie字段,这个是没办法用与授权的,可以理解为IdentityServer4直接指定了Client角色,并不是Identity中的角色概念。

后记

回过头来仔细看官方的文档,ApiResource中的UserClaims就是用来干这个的,折腾了半天,不如当时仔细看看文档了。

到此这篇关于IdentityServer4 QuckStart 授权与自定义Claims的文章就介绍到这了,更多相关IdentityServer4 QuckStart Claims内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • IdentityServer4实现.Net Core API接口权限认证(快速入门)

    什么是IdentityServer4 官方解释:IdentityServer4是基于ASP.NET Core实现的认证和授权框架,是对OpenID Connect和OAuth 2.0协议的实现. 通俗来讲,就是服务端对需要认证授权的资源(客户端请求资源)在外层使用IdentityServer4框架进行封装加壳,用户只能通过获取IdentityServer4颁发的Token令牌才能进行资源访问. 下面开始进入正题,如何快速搭建实现API接口鉴权. 准备:1.下载准备NetCore sdk环境 2.

  • 基于.net4.0实现IdentityServer4客户端JWT解密

    情景:公司项目基于.net4.0,web客户端实现单点登录需要自己解密id_token,对于jwt解密,.net提供了IdentityModel类库,但是4.0中该类库不可用,所以自己实现了解密方法.. 使用了类库:链接地址 下面直接贴代码,直接调用DecodeJWT方法就行,参数为id_token,key默认为空字符串"", 代码 public static IDictionary<string, object> DecodeJWT(string jwttoken,str

  • IdentityServer4 QuckStart 授权与自定义Claims的问题

    最近在折腾IdentityServer4,为了简单,直接使用了官方给的QuickStart示例项目作为基础进行搭建.有一说一,为了保护一个API,感觉花费的时间比写一个API还要多. 本文基于ASP.NET CORE 3.1, IdentityServer4 3.1.3.代码皆为关键代码,贴全了太多了. 好不容易跑起来了,最终的任务要落实到授权的工作上来.在API中使用Authorize用来限制用户的访问. [Route("api/[controller]")] [Authorize(

  • .NET Core授权失败自定义响应信息的操作方法

    前言 在.NET 5之前,当授权失败即403时无法很友好的自定义错误信息,以致于比如利用Vue获取到的是空响应,不能很好的处理实际业务,同时涉及到权限粒度控制到控制器.Action,也不能很好的获取对应路由信息.本文我们来看看在.NET 5中为何要出现针对授权失败的中间件接口?它是如何一步步衍生出来的呢?以及对于授权失败根据实际需要如何自定义响应错误,以及如何获取对应路由信息等等 授权失败自定义响应信息 如下是在.NET 5之前,对于授权处理,我们大多实现自定义的AuthorizationHan

  • 详解IdentityServer4介绍和使用

    目录 一.概述 1.OpenID认证用户的流程 2.OAuth认证用户的流程 3.IdentityServer4对象 二.IdentityServer4实践 1.构建非持久化认证服务项目 2.构建持久化认证服务项目 三.identityserver4实践中遇到的问题 1.identityserver4项目中的认证 2.Access_Token包含其他声明 3.基于identityserver4的授权项目中自定义生成Token 一.概述 前几篇文章介绍到,OWIN提供了一些OAuth2.0认证的机

  • 详解使用JWT实现单点登录(完全跨域方案)

    首先介绍一下什么是JSON Web Token(JWT)? 官方文档是这样解释的:JSON Web Token(JWT)是一个开放标准(RFC 7519),它定义了一种紧凑且独立的方式,可以在各方之间作为JSON对象安全地传输信息.此信息可以通过数字签名进行验证和信任.JWT可以使用秘密(使用HMAC算法)或使用RSA或ECDSA的公钥/私钥对进行签名. 虽然JWT可以加密以在各方之间提供保密,但只将专注于签名令牌.签名令牌可以验证其中包含的声明的完整性,而加密令牌则隐藏其他方的声明.当使用公钥

  • .Net Core 2.2升级3.1的避坑指南(小结)

    写在前面 微软在更新.Net Core版本的时候,动作往往很大,使得每次更新版本的时候都得小心翼翼,坑实在是太多.往往是悄咪咪的移除了某项功能或者组件,或者不在支持XX方法,这就很花时间去找回需要的东西了,下面是个人在迁移.Net Core WebApi项目过程中遇到的问题汇总: 开始迁移 1. 修改*.csproj项目文件 <TargetFramework>netcoreapp2.2</TargetFramework> 修改为 <TargetFramework>net

  • java微信公众号开发(搭建本地测试环境)

    俗话说,工欲善其事,必先利其器.要做微信公众号开发,两样东西不可少,那就是要有一个用来测试的公众号,还有一个用来调式代码的开发环境. 测试公众号 微信公众号有订阅号.服务号.企业号,在注册的时候看到这样的信息,只有订阅号可以个人申请,服务号和企业号要有企业资质才可以.这里所说的微信公众号开发指的是订阅号和服务号. 另外,未认证的个人订阅号有一些接口是没有权限的,并且目前个人订阅号已不支持微信认证,也就是说个人订阅号无法调用一些高级的权限接口,下图就是一个未认证的个人订阅号所具备权限列表,像生成二

  • golang之JWT实现的示例代码

    什么是JSON Web Token? JSON Web Token(JWT)是一个开放标准(RFC 7519),它定义了一种紧凑且自包含的方式,用于在各方之间以JSON方式安全地传输信息.由于此信息是经过数字签名的,因此可以被验证和信任.可以使用秘密(使用HMAC算法)或使用RSA或ECDSA的公钥/私钥对对JWT进行签名. 直白的讲jwt就是一种用户认证(区别于session.cookie)的解决方案. 出现的背景 众所周知,在jwt出现之前,我们已经有session.cookie来解决用户登

  • Java之springcloud Sentinel案例讲解

    一.Sentinel是什么? Sentinel (分布式系统的流量防卫兵) 是阿里开源的一套用于服务容错的综合性解决方案. 它以流量为切入点,从流量控制.熔断降级.系统负载保护等多个维度来保护服务的稳定性. 二.使用步骤 1.下载地址 下载地址:https://github.com/alibaba/Sentinel/releases java -jar sentinel-dashboard-1.7.0.jar 访问:http://localhost:8080 用户名密码:sentinel/sen

  • ASP.NET Core使用JWT自定义角色并实现策略授权需要的接口

    ① 存储角色/用户所能访问的 API 例如 使用 List<ApiPermission> 存储角色的授权 API 列表. 可有可无. 可以把授权访问的 API 存放到 Token 中,Token 也可以只存放角色信息和用户身份信息. /// <summary> /// API /// </summary> public class ApiPermission { /// <summary> /// API名称 /// </summary> pub

  • .Net6集成IdentityServer4 +AspNetCore Identity读取数据表用户且鉴权授权管理API

    目录 前言 1.创建.Net6 API程序 2.建立数据库连接类 3.Program里开始加东西(如果是历史的Net版本,是在StartUp里) 前言 IdentityServer4 实现鉴权.授权,AspNetCore Identity实现数据库用户管理表直接生成. ps:IdentityServer4文档上最后给的例子是 // 配置使用内存存储用户信息,但使用 EF 存储客户端和资源信息, 我初步要实现的是 //数据库存储用户信息   内存存储资源   (下一步资源也放数据库  以后弄好了有

随机推荐