说明:使用password认证模式
jwt提供算法,JwtTokenStore不存储token值,若要存储(Redis)token需要自己额外写token存储及过期和刷新逻辑
1.Oauth配置
声明类
//Oauth2.0配置类
public class OAuth2AuthorizationServeConfig extends AuthorizationServerConfigurerAdapter
//SpringSecurity配置类
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter
//ResourceServer资源配置类
public class ResourceServerConfig extends ResourceServerConfigurerAdapter
//用户信息查询类
public class RenUserDetailsServiceImpl implements UserDetailsService{
@Override
public User loadUserByUsername(String username) throws UsernameNotFoundException{
//查询用户逻辑
return new User();
}
}
1.客户端配置
@Autowired
private PasswordEncoder passwordEncoder;
/**
* 默认的 oauth client_id
*/
public static final String defaultClientId = "coreclientcomponent";
/**
* 默认的 oauth client_secret
*/
public static final String defaultClientSecret = "@CoreRoot305140704202.";
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
InMemoryClientDetailsServiceBuilder builder = clients.inMemory();
builder
.withClient(defaultClientId)
.secret(passwordEncoder.encode(defaultClientSecret))
.scopes("all")
.authorizedGrantTypes("password", "refresh_token","smsCode_type")
.accessTokenValiditySeconds(21600)
.refreshTokenValiditySeconds(86400);
}
2.认证服务配置
@Autowired
private JwtAccessTokenConverter jwtAccessTokenConverter;
/**
* token增加额外信息
* @return
*/
@Bean
public TokenEnhancer tokenEnhancer() {
return new RenTokenEnhancer();
}
/**
* Token存储使用Redis:位置:token.TokenStoreConfig
*/
@Autowired
private TokenStore tokenStore;
@Autowired
private UserDetailsService userDetailsService;
/**
* AuthenticationManager
* 是一个用来处理认证(Authentication)请求的接口。在其中只定义了一个方法authenticate(),该方法只接收一个代表认证请求的Authentication对象作为参数,
* 如果认证成功,则会返回一个封装了当前用户权限等信息的Authentication对象进行返回。
*/
@Autowired
private AuthenticationManager authenticationManager;
/**
* AuthorizationServerEndpointsConfigurer其实是一个装载类,装载Endpoints所有相关的类配置
* (AuthorizationServer、TokenServices、TokenStore、ClientDetailsService、UserDetailsService)。
* @param endpoints
*/
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
endpoints.allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST, HttpMethod.DELETE);
//密码模式
endpoints.authenticationManager(authenticationManager);
//支持刷新令牌
endpoints.userDetailsService(userDetailsService);
//令牌管理
endpoints.tokenStore(tokenStore);
//令牌增强
endpoints.tokenEnhancer(tokenEnhancer());
//token管理
endpoints.tokenServices(getTokenStore(endpoints));
//token解析
endpoints.accessTokenConverter(jwtAccessTokenConverter);
}
/**
* 配置TokenService参数
* @param endpoints
* @return
*/
private DefaultTokenServices getTokenStore(AuthorizationServerEndpointsConfigurer endpoints) {
//整合jwt令牌增强
TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
List<TokenEnhancer> tokenEnhancers = new ArrayList<>();
tokenEnhancers.add(jwtAccessTokenConverter);
tokenEnhancers.add(tokenEnhancer());
tokenEnhancerChain.setTokenEnhancers(tokenEnhancers);
DefaultTokenServices tokenService = new DefaultTokenServices();
tokenService.setTokenStore(endpoints.getTokenStore());
tokenService.setSupportRefreshToken(true);
//使用jwttoken
tokenService.setTokenEnhancer(tokenEnhancerChain);
//token有效期 1小时
tokenService.setAccessTokenValiditySeconds(21600);
//token刷新有效期 15天
tokenService.setRefreshTokenValiditySeconds(3600 * 12 * 15);
tokenService.setReuseRefreshToken(false);
return tokenService;
}
/**
* AuthorizationServerSecurityConfigurer
* 继承自SecurityConfigurerAdapter,
* 也就是一个 Spring Security安全配置提供给AuthorizationServer去配置AuthorizationServer的端点(/oauth/****)的安全访问规则、过滤器Filter。
* /oauth/authorize:授权端点
* /oauth/token:令牌端点
* /oauth/confirm_access:用户确认授权提交端点
* /oauth/error:授权服务错误信息端点
* /oauth/check_token:用于资源服务访问的令牌解析端点
* /oauth/token_key:提供公有密匙的端点,如果使用JWT令牌的话
* @param security
*/
@Override
public void configure(AuthorizationServerSecurityConfigurer security) {
security
//允许用户表单认证
.allowFormAuthenticationForClients()
//匿名可访问/oauth/token_key
.tokenKeyAccess("permitAll()")
//认证后可访问/oauth/check_token
.checkTokenAccess("isAuthenticated()")
;
}
/**
* 令牌
* TokenEnhancer 是 Spring Security OAuth2 中的一个接口,用于在 OAuth2 的令牌(Token)生成或解析过程中进行增强操作。
* @author Rossi
*/
public class RenTokenEnhancer implements TokenEnhancer {
@Override
public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
//在token中存储额外信息
return accessToken;
}
}
@Configuration
public class JwtTokenStoreConfig {
/**
* 自己的算法key值
*/
private String secretKey = "******";
@Bean
public TokenStore tokenStore() {
//将用户信息存储在token中,性能更快
return new JwtTokenStore(jwtAccessTokenConverter());
}
@Bean
public JwtAccessTokenConverter jwtAccessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setSigningKey(secretKey);
return converter;
}
}
2.SpringSecurity配置
@Autowired
private SysUserService sysUserService;
/**
* 登录验证码登录
*/
@Resource
private UserDetailsService userDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}
/**
* 密码模式需要
*/
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception{
return super.authenticationManager();
}
@Override
public void configure(WebSecurity web) {
web.ignoring().antMatchers(HttpMethod.OPTIONS);
}
3.ResourceServer配置
@Override
public void configure(HttpSecurity http) throws Exception {
http
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/oauth/token").permitAll()
.anyRequest().authenticated().and().csrf().disable();
http.headers().frameOptions().sameOrigin().and().httpBasic();
}