@TOC
一、OAuth2.0是什么?
1.1 OAuth2.0简介
OAuth 2.0是目前最流行的授权机制,用来授权第三方应用
OAuth是一种开放协议, 允许用户让第三方应用以安全且标准的方式获取该用户在某一网站,移动或者桌面应用上存储的秘密的资源(如用户个人信息,照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用。
OAuth 1.0协议(RFC5849)作为一个指导性文档发布,是一个小社区的工作成果。
本标准化规范在OAuth 1.0的部署经验之上构建,也包括其他使用案例以及从更广泛的IETF社区收集到的可扩展性需求。
OAuth 2.0协议不向后兼容OAuth 1.0。这两个版本可以在网络上共存,实现者可以选择同时支持他们。
1.2 OAuth2.0官方文档
官网:https://oauth.net/2/ ,官网只有英文版文档,您也可以参考翻译过来的文档,链接:OAuth2 RFC6749中文翻译
OAuth2.0在安全性方面做了比较大的提高,简单来说OAuth2.0就是一种授权协议,可以用来授权,随意点个网站,如图这种网站,用户不想注册,就可以用微信、支付宝登录,就是场景是很常见的,也是OAuth2.0的应用
二、OAuth2.0原理
OAuth2.0是一种授权机制,正常情况,不使用OAuth2.0等授权机制的系统,客户端是可以直接访问资源服务器的资源的,为了用户安全访问数据,在访问中间添加了Access Token机制。客户端需要携带Access Token去访问受到保护的资源。所以OAuth2.0确保了资源不被恶意客户端访问,从而提高了系统的安全性。
2.1 OAuth2.0流程图
引用官方图片介绍OAuth2.0总体流程:
- (A)客户端向从资源所有者请求授权。
- (B)客户端收到授权许可,资源所有者给客户端颁发授权许可(比如授权码code)
- (C)客户端与授权服务器进行身份认证并出示授权许可(比如授权码code)请求访问令牌。
- (D)授权服务器验证客户端身份并验证授权许可,若有效则颁发访问令牌(accept token)。
- (E)客户端从资源服务器请求受保护资源并出示访问令牌(accept token)进行身份验证。
- (F)资源服务器验证访问令牌(accept token),若有效则满足该请求。
三、 OAuth2.0的角色
OAuth2.0定义如下角色:
- 资源所有者(Resource Owner): 能够许可受保护资源访问权限的实体。当资源所有者是个人时,它作为最终用户被提及。
- 用户代理(User Agent): 指的的资源拥有者授权的一些渠道。一般指的是浏览器、APP
- 客户端(Client) 使用资源所有者的授权代表资源所有者发起对受保护资源的请求的应用程序。术语“客户端”并非特指任何特定的的实现特点(例如:应用程序是否在服务器、台式机或其他设备上执行)。
- 授权服务器(Authorization Server): 在成功验证资源所有者且获得授权后颁发访问令牌给客户端的服务器。
授权服务器和资源服务器之间的交互超出了本规范的范围。授权服务器可以和资源服务器是同一台服务器,也可以是分离的个体。一个授权服务器可以颁发被多个资源服务器接受的访问令牌。- 资源服务器(Resource Server): 托管受保护资源的服务器,能够接收和响应使用访问令牌对受保护资源的请求。
四、OAuth2.0授权模式
OAuth2.0有4种授权模式:
- 授权码模式(authorization code)
- 简化模式(implicit)
- 密码模式(resource owner password credentials)
- 客户端模式(client credentials)
其中最常用的是授权码模式,4种授权模式的详细介绍可以参考阮一峰老师的:OAuth 2.0 的四种方式
4.1 授权码模式(authorization code)
授权码(authorization code)方式,指的是第三方应用先申请一个授权码,然后再用该码获取令牌。
官网图片:
从调接口方面,简单来说:
第一步:获取code:
eg:oauthServer+"/oauth/authorize?client_id="+clientId+"&response_type=code&redirect_uri="+redirectUrl+"&scope=all"
如果没有登录,则会跳转到统一身份认证登录页面。如果用户登录了,调用接口后,会重定向到redirect_uri,授权码会作为它的参数第二步:获取access_token
eg:oauthServer+"/oauth/token?code="+code+"&grant_type=authorization_code&client_secret="+clientSecret+"&redirect_uri="+redirectUri+"&client_id="+clientId
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1ODk1MzQ5NzMsInVzZXJfbmFtZSI6Im5pY2t5IiwiYXV0aG9yaXRpZXMiOlsiUk9MRV9hZG1pbiJdLCJqdGkiOiJmMjM0M2Q0NC1hODViLTQyOGYtOWE1ZS1iNTE4NTAwNTM5ODgiLCJjbGllbnRfaWQiOiJvYSIsInNjb3BlIjpbImFsbCJdfQ.LWkN2gC2dBrGTn5uSPzfdW6yRj7jhlX87EE8scY02hI",
"token_type": "bearer",
"expires_in": 59,
"scope": "all",
"user_name": "nicky",
"jti": "f2343d44-a85b-428f-9a5e-b51850053988"
}
- 第三步:访问系统资源,此时统一认证服务会根据该认证客户端权限信息判断,决定是否返回信息。
访问:http://localhost:8084/api/userinfo?access_token=${accept_token}
4.2 简化模式(implicit grant type)
简化模式(implicit grant type)不通过第三方应用程序的服务器,直接在浏览器中向认证服务器申请令牌,跳过了"授权码"这个步骤,因此称简化模式
从调接口方面,简单来说:
- 第一步:访问授权,要传client_id:客户端id,redirect_uri:重定向uri,response_type为token,scope是授权范围,state是其它自定义参数
- 第二步:授权通过,会重定向到redirect_uri,access_token码会作为它的参数
http://localhost:8084/callback#access_token=${accept_token}&token_type=bearer&state=123&expires_in=120
- 第三步:拿到acceptToken之后,就可以直接访问资源
http://localhost:8084/api/userinfo?access_token=${accept_token}
4.3 密码模式(resource owner password credentials)
密码模式中,用户向客户端提供自己的用户名和密码,这通常用在用户对客户端高度信任的情况
从调接口方面,简单来说:
- 第一步:直接传username,password获取token
- 第二步:拿到acceptToken之后,就可以直接访问资源
http://localhost:8084/api/userinfo?access_token=${accept_token}
4.4 客户端模式(client credentials)
客户端模式(client credentials)适用于没有前端的命令行应用,即在命令行下请求令牌
从调接口方面,简单来说:
- 第一步: 获取token
http://localhost:8888/oauth/token?client_id=cms&client_secret=123&grant_type=client_credentials&scope=all
- 第二步:拿到acceptToken之后,就可以直接访问资源
http://localhost:8084/api/userinfo?access_token=${accept_token}
学习必要的理论知识后,还是实践一下才能明白整个流程,详情参考我OAuth2.0系列博客专栏:OAuth2.0系列博客,SpringBoot的参考我系列博客专栏:SpringBoot系列博客