介绍:
spring-security+spring-security-oauth2,实现Oauth2的四种授权方式
用到的工具:
IDEA,Postman
使用到的技术框架依赖
spring security,springboot
先介绍一下四种授权模式:
客户端必须得到用户的授权(authorization grant),才能获得令牌(access token)。OAuth 2.0 对
于如何颁发令牌的细节,规定得非常详细。具体来说,一共分成四种授权类型(authorization
grant),即四种颁发令牌的方式,适用于不同的互联网场景
- 授权码模式(authorization code)(认证级别最高的。可以联想到微信扫码登录京东的场景)
- 密码模式(resource owner password credentials)
- 简化(隐式)模式(implicit)
- 客户端模式(client credentials)
1、授权码模式:
(A)用户访问客户端,后者将前者导向授权服务器。
(B)用户选择是否给予客户端授权。
(C)假设用户给予授权,授权服务器将用户导向客户端事先指定的"重定向URI"(redirection
URI),同时附上一个授权码。
(D)客户端收到授权码,附上早先的"重定向URI",向授权服务器申请令牌。这一步是在客户端
的后台的服务器上完成的,对用户不可见。
(E)授权服务器核对了授权码和重定向URI,确认无误后,向客户端发送访问令牌(access
token)和更新令牌(refresh token)。
2、简化模式
简化模式不通过第三方应用程序的服务器,直接在浏览器中向授权服务器申请令牌,跳过了"授权码"这
个步骤,所有步骤在浏览器中完成,令牌对访问者是可见的,且客户端不需要认证。
这种方式把令牌直接传给前端,是很不安全的。因此,只能用于一些安全要求不高的场景,并且令牌的
有效期必须非常短,通常就是会话期间(session)有效,浏览器关掉,令牌就失效了。
3、密码模式
如果你高度信任某个应用,RFC 6749 也允许用户把用户名和密码,直接告诉该应用。该应用就使用你
的密码,申请令牌,这种方式称为"密码式"(password)。
在这种模式中,用户必须把自己的密码给客户端,但是客户端不得储存密码。这通常用在用户对客户端
高度信任的情况下,比如客户端是操作系统的一部分,或者由一个著名公司出品。而授权服务器只有在
其他授权模式无法执行的情况下,才能考虑使用这种模式
4、客户端模式
客户端模式(Client Credentials Grant)指客户端以自己的名义,而不是以用户的名义,向"服务提供
商"进行授权。
适用于没有前端的命令行应用,即在命令行下请求令牌。一般用来提供给我们完全信任的服务器端服
务。
例子地址:https://gitee.com/Dimple1130/springstudy
相关获取验证操作的步骤、获取URL以及需要添加的配置如下
一、授权码模式
获取授权码
http://localhost:8080/oauth/authorize?
response_type=code
&client_id=client
&redirect_uri=http://www.baidu.com
&scope=all
在认证身份之后,浏览器返回授权码:GVtroX
获取token(postman)
http://localhost:8080/oauth/token
authorization:
选择Basic Auth
Username:client
Password:123123
body:
grant_type:authorization_code
code:GVtroX
redirect_uri:http://www.baidu.com
2、简化模式
简化模式:
authorizedGrantTypes添加一个implicit类型
http://localhost:8080/oauth/authorize?
&response_type=token
&client_id=client
&redirect_uri=http://www.baidu.com
&scope=all
返回结果为:https://www.baidu.com/#access_token=ff1888bf-97d7-4586-8035-606ab0966bee&token_type=bearer&expires_in=3599
带了一个access_token的锚点
3、密码模式
http://localhost:8080/oauth/token?
username=allen
&password=123456
&grant_type=password
&client_id=client
&client_secret=123123
&scope=all
需要配置认证管理器(定义一个AuthenticationManager认证管理器的Bean)、允许表单登录配置
返回结果:
{"access_token":"ff1888bf-97d7-4586-8035-606ab0966bee","token_type":"bearer","refresh_token":"5c397383-9e16-48fe-aaf8-f611b0fc08e7","expires_in":3394,"scope":"all"}
4、客户端模式
http://localhost:8080/oauth/token?
grant_type=client_credentials
&scope=all
&client_id=client
&client_secret=123123
返回结果:
{"access_token":"4e27b802-b9cf-4590-b5dd-6508965f0730","token_type":"bearer","expires_in":3599,"scope":"all"}
其中简化模式与客户端容易记混,现在来对比一下
简化模式 | 客户端模式 | |
描述 |
有些 Web 应用是纯前端应用,没有后端。这时就不能用上面的方式了,必须将令牌储存在前端。 简化模式不通过第三方应用程序的服务器,直接在浏览器中向授权服务器申请令牌,跳过了"授权码"这 |
客户端模式(Client Credentials Grant)指客户端以自己的名义,而不是以用户的名义,向"服务提供商"进行授权。 适用于没有前端的命令行应用,即在命令行下请求令牌。一般用来提供给我们完全信任的服务器端服务 |
请求方式 | 向认证服务器传入字段:
response_type=token client_id redirect_uri scope |
向认证服务器传入字段: grant_type=client_credentials client_id client_secret scope |
返回方式 | URL返回,access_token拼接在#后面,以锚点的形式 | 返回json |