在微服务场景中,身份认证通常是集中处理,这也是有别于单体应用一把梭哈的模式,其中,在微软微服务白皮书中,提供了两种身份认证模式:
网关,没错,原话是If you\'re using an API Gateway, the gateway is a good place to authenticate
STS(security token service)
如果使用网关进行集中身份认证,微服务如果没有设置了额外的安全性来验证消息,就必须确保微服务在没有经过网关的时候,不能直接被访问。从图中也可看到,用户信息是由网关进行转发请求时增加的。
如果使用STS进行集中身份认证,是可以直接访问服务,需要使用安全令牌服务(STS)的专用身份验证单独的服务(微服务)对用户进行身份验证。由STS颁发token,然后在请求微服务时就需要在请求中携带token。
我们文章后续:主要就是围绕着STS安全令牌服务中间件IdentityServer4来具体展开的。
1.引言 1.1 实际遇到的问题在之前一个单体web系统中,采用的是前后端分离,前端是Vue 2.0,后端使用的ASP.NET Web Api 2.0提供后台服务,登录模块采用了JWT(JSON WEB TOKEN)的身份认证方式,在用户请求时后台自定义解析JWT,然后把解析的部分结果装进HttpContext.Principal,供后续授权操作。那时会遇到一个问题,前端并没有mock开发,而是连接后端测试环境开发,前端在开发调试时,后端同步发布最新接口,再加上IIS老版本发布web服务,会有一个初次访问非常慢的问题,这时前端就会炸锅,“后端挂了?请求不到JWT”,这个过程其实挺影响开发效率的,那时就萌生了把身份认证和授权单独作为一个项目部署,由于本身属于项目基础设施,改动的频率几乎为0,业务层面也可以按需拆分,这可能就是我最早微服务思路的萌芽吧!
1.2 其他问题 微信公众号开发做过微信公众号开发,我们大多数应用都希望用户通过微信进行操作,然后留存用户信息,我们需要经过如下步骤:
向微信官方申请AppId,Appsecret,还有单独一个加密密钥
然后请求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
这个code,记住
然后就可以通过code,https://api.weixin.qq.com/sns/oauth2/access_token?appid={0}&secret={1}&code={2}&grant_type=authorization_code在后台获取access_token,openid
access_token是凭证
openid是微信的用户体系
最后就能通过https://api.weixin.qq.com/sns/userinfo?access_token={0}&openid={1}&lang=zh_CN,就能通过上一步中获取到的access_token,获取微信用户的信息
类似的还有华为开放平台鉴权
2.OAuth 2.0无论是微信公众号,还是华为开发平台,他们为了构造自己的生态,运用自己庞大的用户基数,去为第三方提供服务(如果可以的话,顺便收钱),但是他们面临的问题:
不能直接把用户的信息直接暴露,不然就是侵权行为
更不可能把用户的用户名和密码直接暴露
怎么办?第三方应用程序需要知道当前操作的用户身份,就需要身份验证,这时OAuth协议应运而生,OAuth2.0引入了一个授权层,分离两种不同的角色:
客户端
资源所有者(用户)
只有用户同意以后,服务器才能向客户端颁发令牌,客户端通过令牌Token去请求数据,从某种意义上说OAuth2.0是一种委托协议,把原本可能需要用户名和密码才能拿到的数据,通过授权(Authorization)产生的access-token,并以此来进行相关访问。
简单说系统用户允许某个应用代表他们访问用户自己能够控制的资源。
OAuth 2.0包含如下主要内容:
2.1 授权方式实际上,OAuth2.0有4种授权方式
授权码-authorization-code
隐藏式-implicit
密码式-password
客户端凭证-client credentials