最近在折腾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的更多相关文章

  1. IdentityServer4客户端如何获取自定义声明,了解一下?

    前言 久违了各位,之前录制过IdentityServer4的基础视频(https://space.bilibili.com/319652230/#/),有兴趣了解的童鞋可以看一下,只不过未发表成博客. ...

  2. 【.NET Core项目实战-统一认证平台】第十四章 授权篇-自定义授权方式

    [.NET Core项目实战-统一认证平台]开篇及目录索引 上篇文章我介绍了如何强制令牌过期的实现,相信大家对IdentityServer4的验证流程有了更深的了解,本篇我将介绍如何使用自定义的授权方 ...

  3. .net core Identity集成IdentityServer(2) 实现IprofileService接口在accesstoken中增加自定义claims

    导读 1. 如何添加自定义的claims. 前请提要 目前我们拥有了三个web应用. localhost:40010, 验证服务器 localhost:40011, mvc客户端, 充当webapp请 ...

  4. Asp.net Core 系列之--5.认证、授权与自定义权限的实现

    ChuanGoing 2019-11-24 asp.net core系列已经来到了第五篇,通过之前的基础介绍,我们了解了事件订阅/发布的eventbus整个流程,初探dapper ORM实现,并且简单 ...

  5. IdentityServer4 (3) 授权码模式(Authorization Code)

    写在前面 1.源码(.Net Core 2.2) git地址:https://github.com/yizhaoxian/CoreIdentityServer4Demo.git 2.相关章节 2.1. ...

  6. 一看就懂的IdentityServer4认证授权设计方案

    查阅了大多数相关资料,总结设计一个IdentityServer4认证授权方案,我们先看理论,后设计方案. 1.快速理解认证授权 我们先看一下网站发起QQ认证授权,授权通过后获取用户头像,昵称的流程. ...

  7. spring security 授权方式(自定义)及源码跟踪

    spring security 授权方式(自定义)及源码跟踪 ​ 这节我们来看看spring security的几种授权方式,及简要的源码跟踪.在初步接触spring security时,为了实现它的 ...

  8. 认证授权:IdentityServer4 - 各种授权模式应用

    前言: 前面介绍了IdentityServer4 的简单应用,本篇将继续讲解IdentityServer4 的各种授权模式使用示例 授权模式: 环境准备 a)调整项目结构如下:   b)调整cz.Id ...

  9. IdentityServer4系列 | 授权码模式

    一.前言 在上一篇关于简化模式中,通过客户端以浏览器的形式请求IdentityServer服务获取访问令牌,从而请求获取受保护的资源,但由于token携带在url中,安全性方面不能保证.因此,我们可以 ...

随机推荐

  1. vscode回车补全代码

    VsCode设置回车补全代码而不换行 有一部分人不习惯用tab键补全代码,我就是其中之一,习惯了回车补全的我决定设置一波,网上找了很多, 没找到比较详细的,所以自己写一个 有一个叫keybinding ...

  2. 全国职业技能大赛信息安全管理与评估-MySQL弱口令利用

    MySQL读文件 #coding=utf-8 import MySQLdb host = '172.16.1.' for i in range(129,131): tag = host+str(i) ...

  3. C 2012年笔试题

    1指出程序段中的错误:分析错误的原因,并进行修改 1.1函数 swap 将两个字符串(字符数组作实参,长度不超过 100)的内容进行交换 void swap(char *pa,char *pb) { ...

  4. 浅谈VUE,使用watch方法监听父组件传到子组件的数据。

    props:['updateData'], data(){ return{ form: { _name:'', }, } }, 第一步接收数据: props:['updateData']   第二步动 ...

  5. Python-类的特性

    ------------恢复内容开始------------ 类及类的定义 Cat类 类的特殊方法-构造函数.析构函数 class Cat: # 构造函数 def __init__(self, nam ...

  6. SpringBoot 集成ehcache

    1, 项目实在springboot 集成mybatis 的基础上的: https://www.cnblogs.com/pickKnow/p/11189729.html 2,pom 如下,有的不需要加, ...

  7. 使用SpringCloud将单体迁移至微服务

    使用SpringBoot构建单体项目有一段时间了,准备对一个老项目重构时引入SpringCloud微服务,以此奠定后台服务能够应对未知的业务需求. 现在SOA架构下的服务管理面临很多挑战,比如面临一个 ...

  8. mongodb的增加和删除

    一  mongodb中使用insert()方法来增加集合中的文档: db.myTable.insert({name:'arvin',age:12}) //对名为myTable的集合插入数据 插入数据 ...

  9. linux部署win服务 dotnet mono jexus

    .Net Core (dotnet C#应用) dotnet 可以用在linux上运行 C#应用 适用于 SSO 统一身份认证系统 # 安装依赖 yum install libunwind yum i ...

  10. NCEP CFSR数据读取

    一. NCEP CFSR再分析数据,时间分辨率是1小时. 1.整体读取数据情况 clear all setup_nctoolbox tic %% 读取数据文件 wind= ncgeodataset(' ...