前面一篇关于认证授权的文章,已经有较多而且比较好的博客文章介绍了Oauth2的概念和流程。
https://blog.csdn.net/RX_780/article/details/119215001
常用的两种模式主要是授权码模式和密码模式,最终都是为了拿到acces_token(令牌)。
授权码模式:
client_id、client_secret-》code-》token
密码模式:
username、password-》token
主要实现流程:
一、认证服务器配置
@EnableAuthorizationServer
继承AuthorizationServerConfigurerAdapter
ClientDetailsServiceConfigurer:定义客户端详细信息服务的配置器。客户详细信息可以初始化,或者可以引用现有的 store
AuthorizationServerSecurityConfigurer:定义令牌端点上的安全约束
AuthorizationServerEndpointsConfigurer:定义授权和令牌端点以及令牌服务
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private UserService userService;
@Autowired
// @Qualifier("redisTokenStore")
@Qualifier("jwtTokenStore")
private TokenStore tokenStore;
@Autowired
private JwtAccessTokenConverter jwtAccessTokenConverter;
@Autowired
private JwtTokenEnhancer jwtTokenEnhancer;
/**
* 2 使用密码模式需要配置
* 定义授权和令牌端点以及令牌服务
*/
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
// 配置JWT的内容增强器
TokenEnhancerChain enhancerChain = new TokenEnhancerChain();
List<TokenEnhancer> delegates = new ArrayList<>();
delegates.add(jwtTokenEnhancer);
delegates.add(jwtAccessTokenConverter);
enhancerChain.setTokenEnhancers(delegates);
endpoints.authenticationManager(authenticationManager)
.userDetailsService(userService)
.tokenStore(tokenStore)
.accessTokenConverter(jwtAccessTokenConverter)
.tokenEnhancer(enhancerChain);
}
/**
* @Desc 1 定义客户端详细信息服务的配置器。客户详细信息可以初始化,或者可以引用现有的 store
* @Param
*/
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("admin")//配置client_id
.secret(passwordEncoder.encode("admin123456"))//配置client-secret
.accessTokenValiditySeconds(3600)//配置访问token的有效期
.refreshTokenValiditySeconds(864000)//配置刷新token的有效期
.redirectUris("http://www.baidu.com")//配置redirect_uri,用于授权成功后跳转
// .redirectUris("http://localhost:9501/login")//单点登录时配置
.autoApprove(true) // 自动授权
.scopes("all")//配置申请的权限范围
.authorizedGrantTypes("authorization_code","password", "refresh_token");//配置grant_type,表示授权类型
}
/**
* @Desc 3 定义令牌端点上的安全约束
* @Param
*/
@Override
public void configure(AuthorizationServerSecurityConfigurer security) {
security.tokenKeyAccess("isAuthenticated()"); // 获取密钥需要身份认证,使用单点登录时必须配置
}
}
二、资源服务器配置
@EnableResourceServer
继承ResourceServerConfigurerAdapter
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.requestMatchers()
.antMatchers("/user/**");//配置需要保护的资源路径
}
}
三、SpringSecurity配置
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
public void configure(HttpSecurity http) throws Exception {
http.csrf()
.disable()
.authorizeRequests()
.antMatchers("/oauth/**", "/login/**", "/logout/**")
.permitAll()
.anyRequest()
.authenticated()
.and()
.formLogin()
.permitAll();
}
}
四、添加测试接口
@RestController @RequestMapping("/user") public class UserController { @GetMapping("/getCurrentUser") public Object getCurrentUser(Authentication authentication, HttpServletRequest request) { String header = request.getHeader("Authorization"); String token = StrUtil.subAfter(header, "bearer ", false); return Jwts.parser() .setSigningKey("test_key".getBytes(StandardCharsets.UTF_8)) .parseClaimsJws(token) .getBody(); } }
五、授权码测试
启动服务,在浏览器输入:
输入用户名和密码登陆之后返回至百度页面,并且获取的code
https://www.baidu.com/?code=Wfu71k&state=normal
postman根据code获取token。
根据token获取受限制的接口结果
六、密码模式:
授权码和密码模式最基本的流程还是比较简单的,只不过以上只是demo级别的代码,帮助理解oauth2的基本设计流程。