Identity Server 4 - Hybrid Flow - Claims

前一篇 Identity Server 4 - Hybrid Flow - MVC客户端身份验证: https://www.cnblogs.com/cgzl/p/9253667.html

Claims

我不知道怎么样翻译这个词比较好, 所以我一般就不翻译了.

在前一篇文章里, MVC客户端配置身份认证的时候有这么一句话(Startup的ConfigureServices):

JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

官方文档是这样介绍的: “我们关闭了JWT的Claim 类型映射, 以便允许well-known claims.”

如果我把这句话删掉, 然后再看看User.Claims的类型和值:

现在有些claim的类型与ID Token里面的类型名称是不一样, 也有一些claim不见了:

而加上这句话之后, 现在User claim类型的名字就和ID Token里面一样了:

再看一下ID Token:

有一些claims并没有出现在User.Claims里面. 这是因为这个中间件默认情况下会过滤掉一些它认为我们不需要的claim, 例如nbf, amr等.

就先看下面这两种情况吧:

1. 避免claims被默认过滤掉

如果我想让中间件不要过滤掉nbf和, 也就是把nbf和amr从被过滤掉集合里移除, 就可以使用这个方法:

然后再看About页面打印的UserClaims:

这样nbf和amr就不会被过滤掉了(从过滤掉的集合移除了).

2. 删除某些Claims

假如说我这个MVC客户端不需要sid和idp, 那么我可以使用下面的方法:

这是一个扩展方法, 一定要注意它和Remove方法的区别.........

再次操作后, 可以看到这些Claims不见了:

ClaimActions还有其他几个方法, 请自行探索.

用户信息端点 UserInfo Endpoint 

尽管ID Token里面可以包含很多用户的claims, 但是尽量让ID Token小一点比较好. 所以当MVC客户端需要更多用户信息的时候可以手动请求用户信息端点, 这样做也可以获得用户最新的其他信息.

UserInfo Endpoint的官方文档在这: http://openid.net/specs/openid-connect-core-1_0.html#UserInfo

它要求使用GET或者POST进行请求, 但建议使用GET. 此外请求还需要使用Access Token.

这是一个例子:

成功请求的响应结果是一个JSON对象.

首先在IDP里面再添加一个email scope:

然后在配置的Client里面添加这个scope:

最后为TestUser添加email的claim:

回到MVC客户端的Startup, 这里也需要添加email这个scope,

而且还要保证这个email不会出现在claims Identity里面, 这样我在请求用户信息端点的时候才会得到email而不是从User.Claims里面得到:

再次操作后, 可以看到User.Claims里没有出现email:

下面我需要手动发送请求到用户信息端点来获取其他信息:

identity sever 4的这部分文档在: https://identityserver4.readthedocs.io/en/release/endpoints/userinfo.html#identitymodelhttps://github.com/IdentityModel/IdentityModel2

文档提到, 需要为MVC客户端安装IdentityModel这个库:

dotnet add package IdentityModel

随后, 我把获取用户email的代码还是放在About Action里:

首先通过IDP的URI获得discovery document, 然后从中取出UserInfo端点, 从Cookie里得到access token, 并用access token从用户信息端点获得claims, 从这些claims里面取得email并传递到About.cshtml.

相应的修改一下About.html:

重新操作后看About页面:

对MVC客户端使用基于角色对授权

首先需要在IDP那里对两个用户添加role这个claim:

分别是管理员角色和注册用户角色.

OpenID Connect并没有定义关于角色role相关的scope, 所以我还需要自定义一个scope:

第一个参数是scope的名字, 第二个参数是scope的显示名, 第三个参数是它所包含的claim类型, 这里就是“role”.

然后还需要客户端允许请求“roles”这个scope:

IDP这边配置完了, 下面是MVC客户端的配置, 打开MVC的startup, 添加“roles”这个scope:

下面测试, 可以看到在同意页面确实请求了角色“roles”这个scope:

然后同意后却无法从User.Claims里看到角色role 这个claim:

这是因为ASP.NET默认对UserInfo返回的JSON数据里一些常用的顶层claim进行了映射, 以便它们能够出现在User.Claims里面.

我也只需要把JSON里面的role claim, 映射到User.Claims里即可:

再次操作后, 就可以在User.Claims看到角色了:

然后我便可以在MVC客户端的任意地方通过角色来控制用户的访问权限了, 例如:

但是如何把role claim映射成ASP.NET Core MVC可以识别的角色Roles呢?

可以在MVC里这样配置:

该参数主要是配置验证Token的一些东西, 然而它还可以指定客户端的Name 和 Role Claim的类型.

操作后用两个用户分别测试一下, Nick 管理员, 可以访问About:

另一个用户, Dave 注册用户, 则不可以访问About:

这说明角色已经被MVC客户端识别了.

但是对于Dave这个用户来说, 没有权限访问About时, 页面显示非常不友好, 所以下面解决这个问题.

首先建立一个AuthroizationController:

然后建立相关的view:

最后在Startup里面配置, 如果没有权限就跳转到这个Action上:

再次操作后, Dave点击About后就会因为权限不足而跳转到该页面:

今天先到这, 我自己几乎不用MVC, 我主要是做Web API的, 这部分的内容大部分来自官方文档和其他一些资料综合出来的.

代码: https://github.com/solenovex/Identity-Server-4-Tutorial-Code 02部分

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Jerry的SAP技术分享

使用SAP云平台的destination消费Internet上的OData service

通过SAP云平台上的destination我们可以消费Internet上的OData service或者其他通过HTTP方式暴露出来的服务。

4134
来自专栏晓晨的专栏

ASP.NET Core 搭配 Nginx 的真实IP问题

Nginx(Engine X)是一个高性能HTTP和反向代理服务,是由俄罗斯人伊戈尔·赛索耶夫为访问量第二的Rambler.ru站点(俄文:Рамблер)开发...

1522
来自专栏北京马哥教育

史上最全Linux服务器程序规范

作者:且飙丶且珍惜 来源: http://blog.csdn.net/dextrad_ihacker/article/details/51930998 除了网络...

4016
来自专栏博客园

宿主

    ASP.NET Core应用程序需要在宿主中执行.宿主必须实现IWebHost接口,这个接口暴露了功能和服务的集合,以及Start方法。宿主通常使用We...

2083
来自专栏张善友的专栏

Microsoft Sync Framework 2.1 软件开发包 (SDK)

Sync Framework 2.1 引入了新功能,这些功能支持您计算机上的 SQL Server 或 SQL Server Compact 数据库与 SQL ...

2067
来自专栏coder修行路

让你用sublime写出最完美的python代码--windows环境

 至少很长一段时间内,我个人用的一直是pycharm,也感觉挺好用的,也没啥大毛病 但是pycharm确实有点笨重,啥功能都有,但是有很多可能这辈子我也不会用到...

1.2K6
来自专栏王磊的博客

WebClient 访问间歇性返回403解决方案

说明:前段时间做的一个项目莫名的返回403的错误,这种情况也多大是程序员最不喜欢的了,没办法先来分析一下错误信息。之前的代码如下: WebClient webc...

46411
来自专栏北京马哥教育

运维人必收藏的最全Linux服务器程序规范

除了网络通信外,服务器程序还必须考虑许多其他细节问题,零碎,但基本上都是模板式的。

1870
来自专栏晓晨的专栏

ASP.NET Core 搭配 Nginx 的真实IP问题

Nginx(Engine X)是一个高性能HTTP和反向代理服务,是由俄罗斯人伊戈尔·赛索耶夫为访问量第二的Rambler.ru站点(俄文:Рамблер)开发...

1930
来自专栏角落的白板报

将 ASP.NET Core 2.0 项目升级至 ASP.NET Core 2.1.3X

项目的例子直接使用https://github.com/52ABP/52ABP.School 作为对象,毕竟他正好是.NET CORE 2.0的版本。

851

扫码关注云+社区

领取腾讯云代金券