springSecurityOAuth2
前后端分离的场景,会采用基于token的认证方式,就需要用到spring security oauth2,是spring-security框架的一个子模块
作为一个服务提供商的角色,需要两大块内容,一个是认证服务器,一个是资源服务器,所谓认证服务器其实可以简单理解为就是生成token的逻辑,所谓资源服务器,就是我们的业务代码。这二者只是一个逻辑上的概念,并不是物理上独立的两台服务器。
角色
客户端
客户端本身不存储任何的资源,需要通过资源拥有者的授权去请求资源服务器的资源,比如:Andriod客户端、IOS客户端、浏览器端、微信客户端
资源拥有者
通常为用户,也可以是应用程序,既该资源的拥有者。
授权服务器(认证服务器)
来对资源拥有者的身份进行认证、对访问资源进行授权。客户端要想访问资源需要通过认证服务器由资源拥有者授权后可访问。
常用术语
- 客户凭证 (client Credentials): 客户端的ClientID和密码用于认证客户。
- 令牌(tokens): 授权服务器在接受到用户的请求后,颁发的访问令牌
- 作用域(scopes): 客户请求访问令牌时,由资源拥有者额外制定的细分权限
常用令牌
- 授权码:仅用于授权码授权类型,用于交换获取访问令牌和刷新令牌
- 访问令牌:用于代表一个用户或服务直接去访问受保护的资源
- 刷新令牌:用于去授权服务器获取一个刷新访问令牌
- BearerToken :不管谁拿到Token都可以访问资源,类似现金
- Proof of Possession (Pop) Token:可以校验 client 是否对Token有明确的拥有权
认证服务器
app的认证服务器配置类
@EnableAuthorizationServer注解表示为认证服务器,demo引入了app,所以demo现为认证服务器启动时会创建client-id和client-secret
security.oauth2.client.client-id = 6abb1077-3205-482f-8e86-bcc757766a8a
security.oauth2.client.client-secret = cbd1f3ae-13ac-40fe-89f0-e5113fc04e3c
为了避免每次重启输入的clientid的繁琐,在配置文件中配置一下clientid和clientsecret
授权码模式
获取授权码
访问 url=/oauth/authorize
它后面需要参数:
response_type=code 必填value:code
访问出现以下报错信息
security5+ 认证默认为表单了也就是http.formLogin(),创建AppSecurityConfig
@Configuration
public class AppSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Override
protected void configure(HttpSecurity http) throws Exception {
//security5+ 认证默认为表单了也就是http.formLogin()
http.httpBasic();
}
}
认证服务器需要知道三件事
- 哪个应用在请求授权
通过client_id确认是哪个应用,每个应用注册时分配一个唯一的client_id
2. 请求我的哪个用户授权
用户登陆输入的用户名和密码,UserDetailsServiceImpl
3. 给你什么授权
请求什么样的权限,是通过scope参数带入,scope参数是认证服务器自定义的输入用户名和密码,走UserDetailsServiceImpl.loadUserByUsername方法
再访问出现以下报错信息
需要配置授权码回调域
security:
oauth2:
client:
client-id: wangzhilei
client-secret: 123456
registered-redirect-uri: http://www.example.com
再次访问
这个页面类似QQ,微信扫码的页面
同意授权后返回授权码:https://www.example.com/?code=2vaBOy
拿到这个授权码以后我们就可以请求token了
根据授权码获取token
- 用postman完成,指定请求路径为/oauth/token,POST请求
- Authonzation
具体设置:
TYPE: Basic Auth
username: client_id
password: client_secret
Body
form-data
grant_type: authorization_code
code: 2vaBOy //获取的授权码
client_id: wangzhilei
scope: all
redirect_uri: http://www.example.com
隐式授权码模式
不同点:
- 参数response_type=token
- 返回token,不是授权码,少一步
密码模式
参数和授权码不同 这种模式适用于公司内相互信任的应用之间,可以直接提供用户名密码
POST请求
获取token url: /oauth/token
Body:x-www-form-urlencoded
grant_type: password
scope: all
username: jone
password: 123456
Authorization: 与授权码获取token一样
资源服务器
资源服务配置类,@EnableResourceServer开启资源服务器
@Configuration
@EnableResourceServer
public class ResourceServerConfig {
}
请求资源
获取token后,在请求
OAuth2.0