点击上方“
小姚同学技术栈 ”快速关注我哟!
本篇文章主要讲解基于spring-cloud-starter-oauth2搭建的认证中心和资源服务器的微服务项目。项目不仅仅简单的demo,项目的出发点在于实战应用。项目为笔者花了不少时间和精力整理出来的,只需要稍微调整就可应用于实际项目当中,并且项目包含大量注释,不仅可以让你会用,也可让你了解到一些流程、一些原理上的东西。认证中心完成密码模式、授权码模式、刷新token模式、简化模式、以及自定义的手机号验证码模式。
功能
- 密码模式
- 自定义手机验证码模式
- 授权码模式
- 简化模式
- 刷token模式
- 退出测试接口
- 简单授权页面
- 不需要accessToken测试接口
- 需要accessToken测试接口
- 需要特定权限测试接口
- scope测试接口
认证验证流程
这里简单做下密码模式的认证和accessToken验证流程,授权码模式和简化模式稍微有点不一样,授权码模式和简化模式都是先跳到认证中心的授权页面,授权成功后回调回调地址,并且携带参数code或accessToken。
认证中心核心代码
AuthorizationConfig.java
/**
* 认证配置
* @author: yaohw
* @create: 2019-09-30 16:12
**/
@Configuration
@EnableAuthorizationServer
public class AuthorizationConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private UserDetailsServiceImpl userDetailsService;
@Autowired
private ClientDetailsServiceImpl clientDetailsService;
@Autowired
private RedisConnectionFactory redisConnectionFactory;
@Autowired
private RedisTemplate redisTemplate;/**
* 配置token存储,这个配置token存到redis中,还有一种常用的是JwkTokenStore
* jwt的缺点已发布令牌不可控
* @return
*/@Beanpublic TokenStore tokenStore() {
return new RedisTokenStore(redisConnectionFactory);
}/**
* 配置授权码模式授权码服务(存授权码和删除授权码),不配置默认为内存模式
* @return
*/@Primary@Beanpublic AuthorizationCodeServices authorizationCodeServices() {
return new RedisAuthorizationCodeServices(redisConnectionFactory);
}/**
* 配置客户端详情(根据客户的id查询客户端)
* @param clients
* @throws Exception
*/@Overridepublic void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.withClientDetails(clientDetailsService);
}@Overridepublic void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
// 采用token转jwt,并添加一些自定义信息(token增强)// 默认使用随机UUID生成的token
TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
tokenEnhancerChain.setTokenEnhancers(
Arrays.asList(jwtAccessTokenConverter(),tokenEnhancer()));
endpoints.tokenEnhancer(tokenEnhancerChain)// 配置token存储,一般配置redis存储
.tokenStore(tokenStore())// 配置认证管理器
.authenticationManager(authenticationManager)// 配置用户详情server,密码模式必须
.userDetailsService(userDetailsService)// 配置授权码模式授权码服务,不配置默认为内存模式
.authorizationCodeServices(authorizationCodeServices())// 配置grant_type模式,如果不配置则默认使用密码模式、简化模式、验证码模式以及刷新token模式,如果配置了只使用配置中,默认配置失效// 具体可以查询AuthorizationServerEndpointsConfigurer中的getDefaultTokenGranters方法
.tokenGranter(tokenGranter(endpoints));// 配置TokenServices参数
DefaultTokenServices tokenServices = new DefaultTokenServices();
tokenServices.setTokenStore(endpoints.getTokenStore());// 是否支持刷新Token
tokenServices.setSupportRefreshToken(true);
tokenServices.setReuseRefreshToken(true);
tokenServices.setClientDetailsService(endpoints.getClientDetailsService());
tokenServices.setTokenEnhancer(endpoints.getTokenEnhancer());// 设置accessToken和refreshToken的默认超时时间(如果clientDetails的为null就取默认的,如果clientDetails的不为null取clientDetails中的)
tokenServices.setAccessTokenValiditySeconds((int) TimeUnit.HOURS.toSeconds(2));
tokenServices.setRefreshTokenValiditySeconds((int) TimeUnit.DAYS.toSeconds(30));
endpoints.tokenServices(tokenServices);
}/**
* jwt格式封装token
* @return
*/@Beanpublic JwtAccessTokenConverter jwtAccessTokenConverter() {
JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter();// 设置jwt加解密秘钥,不设置会随机一个
jwtAccessTokenConverter.setSigningKey("yaohw");return jwtAccessTokenConverter;
}/**
* token增强,添加一些元信息
*
* @return TokenEnhancer
*/@Beanpublic To