前言
互联网时代,对信息和资源的保护越发苛刻,在所有应用中授权和认证是必不可少缺少的一部分。如果一个应用没有授权和认证那么这个应用就是不完整或者说不安全的应用。在.Net平台给我们提供了一套完整的授权认证框架,那就是IdentityServer4。它实现了OpenId Connect和OAuth2.0协议的认证授权。
授权认证
很多人喜欢把授权和认证混为一谈,但是其实授权(Authorization)和认证(Authentication)是有区别的。
Authorization(授权) - 侧重点是用户能干嘛,而不关心用户是谁。
Authentication(认证) - 侧重点是用户是谁,而不是用户能干嘛。
OpenId
OpenID 是一个以用户为中心的数字身份识别框架,是一个以URL为身份标识的分散式身份验证解决方案,它具有开放、分散、自由等特性。
OpenID相关基本术语:
用户 - 想要向某个网站表明身份的人。
标识 - 用户用以标识其身份的URL。
身份提供者 - 提供OpenID URL注册和验证服务的服务提供者。
依赖方 - 想要对最终用户的openId进行验证的网站应用。
举个例子, 我使用QQ(身份提供者)登陆京东(依赖方),我打开京东主页点击QQ登陆并不会要我输入我的QQ账号和密码,会先跳转到QQ授权登陆页面,当你扫码或者密码登陆的时候QQ会返回给京东一个OpenId,京东就会拿着这个OpenId来问QQ你这里是不是有这么一个用户。
OpenId关注的是Authentication(认证)。
OAuth2
OAuth是当下比较流行的授权第三方应用读取用户的资源的机制。OAuth能在不涉及到用户的账号信息的情况下,读取用户的一些资源信息。
举个例子,每周都会有保洁阿姨来家里打扫,但是保洁阿姨并不知道我家大门的密码,所以每次保洁阿姨在要上门的时候会在app上申请获取一个临时密码,当我收到保洁阿姨的申请后,确认给予临时密码后保洁阿姨就能通过这个密码进入房子啦。
我就是用户,家,和房间就是我的资源,临时密码是token。阿姨是第三方应用。阿姨申请临时密码需要进入我的家(第三方应用申请读取我的数据),我(用户)收到申请后给予临时密码(用户确认授权读取数据)。阿姨收到临时密码进入房间(获取到相应的token读取数据)。
但是临时密码(token)还是有很多局限性的,比如时效性(规定时间内使用才有效),局限性(只能开一次门,不能进去我私人房间),我还可以在中途撤销授权,使临时密码(token)无法进去我的房间(无法读取我的数据)。
授权过程
(A)用户打开客户端以后,客户端要求用户给予授权。(阿姨打开某公寓App申请临时密码)
(B)用户同意给予客户端授权。(我同意给予临时密码)
(C)客户端使用上一步获得的授权,向认证服务器申请令牌。(同意后,向某某公寓后台申请临时密码)
(D)认证服务器对客户端进行认证以后,确认无误,同意发放令牌。(某某公寓后台确认我同意给予临时密码后,给阿姨发放临时密码)
(E)客户端使用令牌,向资源服务器申请获取资源。(阿姨使用临时密码来开门)
(F)资源服务器确认令牌无误,同意向客户端开放资源。(密码锁收到临时密码验证后开门)
OAuth关注的是Authorization(授权)。
OpenId Connect
OpenID Connect简称OIDC。因为OAuth2是一个授权协议,它无法提供完善的身份认证功能。所以它在OAuth2上构建了一个身份层,是一个基于OAuth2协议的身份认证标准协议。OIDC使用OAuth2的授权来为第三方客户端提供用户的身份认证,并把对应的身份认证信息传递给客户端,且可以适用于各种类型的客户端,并且完全兼容OAuth2,也就是说你搭建了一个OIDC的服务后,也可以当作一个OAuth2的服务来用。
术语介绍
User - 用户。
Client - 客户端。
IdentityServer - 授权认证服务器。
Resources - 需要保护的资源。
Access Token - 访问令牌,允许用户哪些资源。
Identity Token - 身份令牌,用户确认用户身份。
JWT
Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该token也可直接被用于认证,也可被加密。
JWT是由三段字符串拼接而成的,使用 .
分割的。
eyJhbGciOiJSUzI1NiIsImtpZCI6IjIxNmd3ZUVTZTA3d29hSDhpWHAzMUEiLCJ0eXAiOiJhdCtqd3QifQ.eyJuYmYiOjE1NzY2NTYwOTMsImV4cCI6MTU3NjY1OTY5MywiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo1MDAzIiwiYXVkIjoiQXBpX0EiLCJjbGllbnRfaWQiOiJjbGllbnRfYSIsInNjb3BlIjpbIkFwaV9BIl19.kdszQIZFTS8aURbF5lIL1-qFzkJ79plH0seM4TsrTPdZoWakJVTH76-qmRpu6H6eaQt7U10R-Y8fn5N2FFh6XHRuDufEsDL8R2Tv7Cu0qbHKHTi-LgZcU2CxM22RyL6Df7Z0IpG5uEQqJ2LyxHJg3W-D3TgSNXUA8ge87ghGrhLRQ8hywH5gM4EZy9lKO7vMZml1IIfuyXTC8FU-HUn6-ZmvC1mADlAQJv84WHyg7fzzgNXqztvSyXA2p6jJG5FDgAjA9-yWnqJPxlZe7-Qi5Dj67lEF9kSII0tblV8JpxxJTpUvM2iPMLKWw77HDGaZkfAUu9WsbpQv-zWXPBBpbw
我们通过jwt.io解析出来。
第一部分Hrader
alg - 签名算法
kid - 密钥的Id
typ - token类型
这三个参数是最常见的。d
第二部分PayLoad
nbf - 生效时间
exp - 过期时间
iss - 令牌发放者
chlien_Id - 发放客户端id
aud - 令牌接收方
scope - 可访问资源
在PayLoad中可以放置任何你想要的参数。
第三部分Signature
Signature 是对前两部分的签名,防止数据篡改。
JWT的认证过程
1.用户使用账号密码或别的方式登陆
2.服务器接受到登陆请求后生成一个jwt token
3.服务器把jwt token返回给客户端
4.客户端在请求资源在Header中的authorization带上jwt token
5.服务器对jwt进行验签,验签成功后根据PayLoad中的信息判断认证是否通过
6.响应客户端结果
授权方式-后面有实现的传送门
Client Credentials - 客户端授权模式。- 实现传送门
Resource Owner Password Credentials - 密码模式。- 实现传送门
Implicit - 授权码简化模式。
Authorization Code - 授权码模式。
总结
都是自己一边学习IdentityServer4一边写,每种模式后都有实现传的送门,文中如果有神马错误请大佬们在评论区指出。