在微服务场景中,身份认证通常是集中处理,这也是有别于单体应用一把梭哈的模式,其中,在微软微服务白皮书中,提供了两种身份认证模式:
如果使用网关进行集中身份认证,微服务如果没有设置了额外的安全性来验证消息,就必须确保微服务在没有经过网关的时候,不能直接被访问。从图中也可看到,用户信息是由网关进行转发请求时增加的。
如果使用STS进行集中身份认证,是可以直接访问服务,需要使用安全令牌服务(STS)的专用身份验证单独的服务(微服务)对用户进行身份验证。由STS颁发token,然后在请求微服务时就需要在请求中携带token。
我们文章后续:主要就是围绕着STS安全令牌服务中间件IdentityServer4来具体展开的。
在之前一个单体web系统中,采用的是前后端分离,前端是Vue 2.0
,后端使用的ASP.NET Web Api 2.0
提供后台服务,登录模块采用了JWT(JSON WEB TOKEN)
的身份认证方式,在用户请求时后台自定义解析JWT,然后把解析的部分结果装进HttpContext.Principal
,供后续授权操作。那时会遇到一个问题,前端并没有mock开发,而是连接后端测试环境开发,前端在开发调试时,后端同步发布最新接口,再加上IIS老版本发布web服务,会有一个初次访问非常慢的问题,这时前端就会炸锅,“后端挂了?请求不到JWT”,这个过程其实挺影响开发效率的,那时就萌生了把身份认证和授权单独作为一个项目部署,由于本身属于项目基础设施,改动的频率几乎为0,业务层面也可以按需拆分,这可能就是我最早微服务思路的萌芽吧!
做过微信公众号开发,我们大多数应用都希望用户通过微信进行操作,然后留存用户信息,我们需要经过如下步骤:
https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx6953deeefe22a83b&redirect_uri=your_address&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect
redirect_uri
指定的网址,且还会在querystring
加上code
https://api.weixin.qq.com/sns/oauth2/access_token?appid={0}&secret={1}&code={2}&grant_type=authorization_code
在后台获取access_token,openid
https://api.weixin.qq.com/sns/userinfo?access_token={0}&openid={1}&lang=zh_CN
,就能通过上一步中获取到的access_token,获取微信用户的信息类似的还有华为开放平台鉴权
无论是微信公众号,还是华为开发平台,他们为了构造自己的生态,运用自己庞大的用户基数,去为第三方提供服务(如果可以的话,顺便收钱),但是他们面临的问题:
怎么办?第三方应用程序需要知道当前操作的用户身份,就需要身份验证,这时OAuth协议应运而生,OAuth2.0引入了一个授权层,分离两种不同的角色:
只有用户同意以后,服务器才能向客户端颁发令牌,客户端通过令牌Token去请求数据,从某种意义上说OAuth2.0是一种委托协议,把原本可能需要用户名和密码才能拿到的数据,通过授权(Authorization)产生的access-token,并以此来进行相关访问。
简单说系统用户允许某个应用代表他们访问用户自己能够控制的资源。
OAuth 2.0包含如下主要内容:
实际上,OAuth2.0有4种授权方式
不管哪一种授权方式,第三方应用申请令牌之前,都需要像微信公众号开发那样,必须先到系统备案,说明自己的身份,然后会拿到两个身份识别码:客户端 ID(client ID)和客户端密钥(client secret)。这是为了防止令牌被滥用,没有备案过的第三方应用,是不会也不可能拿到令牌的。
代表资源所有者在被保护的资源那里的一些权限,可以把被保护的资源分为不同的scope,这个粒度由开发者自定义,常见的有角色
上一节说过,OAuth 2.0是一种授权机制,是一种委托协议,但是不是一个身份认证协议。OAuth2.0的Access Token不含有身份认证信息,也不是为客户端准备的,本身也不对客户端透明,Access Token真正的受众是被保护的资源。
? 当然我们不排除一些简单的系统鉴权要求,它只需限制对是否具有有效安全令牌的用户的访问,并不需求身份认证。
? OAuth2.0设计的Access Token不含有身份认证信息,但是JWT具有自包含特点,其实我们是可以把Access-Token设计为即具有身份信息,又包含授权信息。在一些简单的单体应用中,把身份认证和授权揉在一起,根据Access_Token解析身份信息和然后再根据身份信息,配合设计的权限规则(db存储)过滤请求,的确可以这样做,事实上有一些开源项目,包括我自己,都这样干过。
? 在一些实际场景下,这种使用access-token作为身份认证的凭据是成立的,因为token是经过身份认证后,刚被创建的,再加上后续验证与数据存储的交互,可以确保无虞。
? 但是如果是在OAuth2.0中,这并不是获取access-token的唯一方法。Refresh Token和assertions可以在用户不存在的情况下获取access token。而在某些情况下,用户无需身份验证即可获得access token。另外用户不存在,access-token通常还会存在很长时间。记住重要的一点:OAuth是一个授权协议,保护的是资源,突出一个保护,那么必须保证用户是存在的;access-token受众是受保护的资源,客户端是授权的提出者,因此受保护的资源不能仅通过token的单独存在来判断用户是否存在,因为 OAuth 协议的性质和设计,在客户端和受保护资源之间的连接上,用户是不可用的。
当应用程序需要知道当前用户的身份时,就需要进行身份认证。通常,这些应用程序代表该用户管理数据,并需要确保该用户只能访问允许他访问的数据。
目前最常见的身份验证协议是SAML2p、WS-Federation和OpenID Connect——SAML2p是最流行和部署最广泛的。
OpenID Connect是三者中最新的一个,但是却被认为是未来的发展方向,因为它对现代应用程序具有最大的潜力。它从一开始就为移动应用场景而构建,并被设计为对API友好。
OpenID Connect
OAuth 2.0与OpenID Connect1.0 映射表
OAuth2.0 | OpenID Connect 1.0 |
---|---|
资源所有者 | 用户 |
客户端 | 依赖方 |
授权服务器+被保护资源 | 身份提供商 |
OpenId Connect 1.0包含如下主要内容:
包含了用户的认证信息
获取用户信息
一组标识身份的scopes和claims
下一篇我们将正式开始介绍对OpenID Connect+OAuth2.0这两种协议的实现中间件:IdentityServer4,其经过高度优化,可以解决当今移动、本机和web应用程序等典型的安全问题。
在不同的文献对可能会同一角色使用不同的术语,所以IdentityServer又可称为安全令牌服务(STS)、身份提供者(IDP)、授权服务器(AuthServer)、IP-STS等等。它的主要职责也就是OAuth2.0与OpenID Connect职责的综合,
也是IdentityServer4的职责:
我们来回顾一下两个协议的要点,
也是IdentityServer4的要点:
我们将在后续文章中一一对应职责与要点
http://www.ruanyifeng.com/blog/2019/04/oauth_design.html
http://www.ruanyifeng.com/blog/2019/04/oauth-grant-types.html
https://www.cnblogs.com/linianhui/p/authentication-based-on-oauth2.html#auto-id-3
https://www.cnblogs.com/linianhui/p/oauth2-extensions-protocol-and-json-web-token.html#auto_id_2
https://www.cnblogs.com/linianhui/p/oauth2-authorization.html#auto_id_17
https://www.cnblogs.com/linianhui/p/oauth2-extensions-protocol-and-json-web-token.html#auto_id_2
https://www.cnblogs.com/linianhui/p/oauth2-extensions-protocol-and-json-web-token.html#auto-id-2
https://www.scottbrady91.com/OpenID-Connect/OpenID-Connect-Flows
https://identityserver4.readthedocs.io/en/latest/intro/big_picture.html
【One by One系列】IdentityServer4(一)OAuth2.0与OpenID Connect 1.0
原文:https://www.cnblogs.com/RandyField/p/13270315.html