授权框架使得第三方获取对用户的资源的访问
eg:bilibili可以去微信服务器获取你的头像、昵称、openid等
术语 | |
专业称呼 | 通俗叫法 |
资源所有者 | 用户 |
资源服务器 | 保存用户信息的服务器并且能验证令牌是否合法 |
客户端 | 第三方应用服务 |
授权服务器 | 发送令牌到第三方服务器 |
1、授权码模式、
最常用的模式,前后端分离,避免令牌泄露。
隐式模式、密码模式、客户端模式
一、spring security OAuth2
1.1、授权服务器
-
- authorize endpoint:授权端点,进行授权
- token endpoint : 令牌端点,授权拿到对应的token
- introspection endpoint: 校验端点,校验token合法性
- revocat endpoint : 撤销端点,撤销授权
二、实际案例 授权码模式
@Configuration
@EnableWebSecurity //启用security
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()//关闭csrf
.authorizeRequests()
.antMatchers("/oauth/**","/login/**","logout/**").permitAll()//放行
.anyRequest()
.authenticated()//其他请求认证
.and()
.formLogin()
.permitAll();//表单登录放行
}
}
授权服务器配置
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
//配置client-id
.withClient("admin")
//配置client-secret
.secret(passwordEncoder.encode("112233"))
//配置令牌有效时间
.accessTokenValiditySeconds(3600)
//配置授权成功后重定向的地址
.redirectUris("http://www.baidu.com")
//配置方位all
.scopes("all")
//配置grant-type 授权类型 authorization_code 授权码模式
.authorizedGrantTypes("authorization_code");
}
资源服务器核心配置
/**
* 资源管理器的放行设置
* @param http the current http filter configuration HTTP当前HTTP过滤配置
* @throws Exception
*/
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest()
.authenticated()//所有请求需要认证
.and()
.requestMatchers()
.antMatchers("/user/**");
}
测试:
2.1获取授权码(这里的这些参数必须与之前在授权服务器上配置的参数一致,否则无法拿到token)
http://localhost:8082/oauth/authorize?response_type=code&client_id=admin&redirect_url=http://www.baidu.com&scope=all
2.2、会携带上授权码
https://www.baidu.com/?code=4Gjsg2
2.3、带着code去申请token
http://localhost:8082/oauth/token
返回token
b656a8f0-6393-4406-a2e8-73f562aa38aa
{
"access_token": "b656a8f0-6393-4406-a2e8-73f562aa38aa",
"token_type": "bearer",
"expires_in": 3599,
"scope": "all"
}
2.4、拿着令牌去资源服务器请求资源
@GetMapping("/getCurrentUser")
public Object getCurrentUser(Authentication authentication){
return authentication.getPrincipal();
}
返回需要的内容完成了整个 授权码模式认证过程
{
"password": null,
"username": "admin",
"authorities": [
{
"authority": "ROLE_sale"
},
{
"authority": "admin"
}
],
"accountNonExpired": true,
"accountNonLocked": true,
"credentialsNonExpired": true,
"enabled": true
}
三、实际案例:密码模式
修改授权配置类中类型为password
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
//todo 后期这些都是可以使用查询的方式
//配置client-id
.withClient("admin")
//配置client-secret
.secret(passwordEncoder.encode("112233"))
//配置令牌有效时间
.accessTokenValiditySeconds(3600)
//配置授权成功后重定向的地址
.redirectUris("http://www.baidu.com")
//配置范位all
.scopes("all")
//配置grant-type 授权类型 authorization_code 授权码模式 password 密码模式
.authorizedGrantTypes("password");
}
/**
* 密码模式配置
* @param endpoints the endpoints configurer
* @throws Exception
*/
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager)
.userDetailsService(userService);
}
直接申请token 不许要回调发送授权码在申请token
{
"access_token": "8217fb9e-3e2a-4467-bcfd-541206afca4b",
"token_type": "bearer",
"expires_in": 3599,
"scope": "all"
}
{
"password": null,
"username": "sen",
"authorities": [
{
"authority": "ROLE_sale"
},
{
"authority": "admin"
}
],
"accountNonExpired": true,
"accountNonLocked": true,
"credentialsNonExpired": true,
"enabled": true
}