一.SpringSecurityOAuth简介
grant_type为授权模式password为密码模式
@EnableAuthorizationServer表示定义认证服务器
@EnableResourceServer表示定义资源服务器
二.Token处理
TokenStore用于定义Token存储
TokenEnhancer用于定制化Token,往里面添加信息
- 基本Token参数配置
- 过期时间,接受什么grant_type,怎么存都是可以配的,需要继承AuthorizationServerConfigurerAdapter(并实现configure方法)
- 在参数为endpoints的configure方法中设置token包含什么信息
- 在参数为clients的方法中设置token的存储(是inMemory还是到数据库中),接受什么grant_type,过期时间设置等等
- 使用JWT替换默认的Token
- JWT:Json Web Token令牌标准
- 自包含:里面包含有意义的信息的,自定义,原始的Token是通过UUID生成的
- 密签:首先发送的token中是不会包含密码这样关键信息的,其次token是可以经过指定密钥进行签名的(签名是防止被篡改)
- 可扩展:包含的信息是可以自定义的,故可以进一步添加需要的信息
- 配置
- 需要配置JWTTokenStore的Bean(用于存取)
- 需要配置JWTAccessTokenConverter的Bean(用于进行签名)
@Bean
public JwtAccessTokenConverter jwtAccessTokenConverter() {
JwtAccessTokenConverter accessTokenConverter = new JwtAccessTokenConverter();
accessTokenConverter.setSigningKey("");//设置密钥
return accessTokenConverter;
}
- 配置JWTTokenEnhancer的Bean(用于向Token中添加对应的内容)
- 自定义一个类SelfJwtTokenEnhancer实现TokenEnhancer
public class SelfJwtTokenEnhancer implements TokenEnhancer{
@Override
public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication){
//里面设置往Token中加的内容
Map<String, Object> info = new HashMap<>();
info.put("company","jackCompany")
//accessToken实际的类型是DefaultOAuth2AccessToken
((DefaultOAuth2AccessToken)accessToken).setAdditionalInformation(info);//设置附加信息
return accessToken;
}
}
- 定义JWTTokenEnhancer用于返回自定义的Enhancer
@Bean
public TokenEnhancer jwtTokenEnhancer() {
return new SelfJwtTokenEnhancer();
}
- 添加到AuthorizationServerConfigurerAdapter实现的方法中
public class SelfAuthorizationServerConfigurer extends AuthorizationServerConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private TokenStore tokenStore;
@Autowired
private JwtAccessTokenConverter jwtAccessTokenConverter;
@Autowired
private TokenEnhancer jwtTokenEnhancer;
@Override
public void configure(AuthenticationServerEndpointsConfigurer endpoints) throws Exception{
endpoints.tokenStore(tokenStore)
.authenticationManager(authenticationManager)
.userDetailService(userDetailsService)
TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();//生成一个增强器链
List<TokenEnhancer> enhancers = new ArrayList<>();
enhancers.add(jwtTokenEnhancer);
enhancers.add(jwtAccessTokenConverter);
tokenEnhancerChain.setEnhancers(enhancers);//在增强器链中添加增强器内容
endpoints.tokenEnhancer(tokenEnhancerChain)
.accessTokenConverter(jwtAccessTokenConverter);
}
}
- 扩展和解析JWT的信息
- 可以在jsonwebtoken.io中输入token查看对应的payload(token包含的信息)
- 如果直接在接口的参数中获得Authentication对象,可见其中的内容是没有添加的Enhancer中的内容的,只会有token自身携带的Authentication内容,所以我们需要自定义代码将添加的内容取出
- 自定义解析JWT
- 引入外部依赖
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
</dependency>
- 从请求中获取Token内容并解析
@GetMapping("/me")
public void getTokenInfo(HttpServletRequest request){
String header = request.getHeader("Authentication");
String token = StringUtils.substringAfter(header,"bearer ");//获取具体token信息
Claims claims = Jwts.parser().setSignKey("设置的key").parseClaimJwt(token).getBody();//将token转成Claims对象
String company = (String)claims.get("company");//通过get获得存入token的信息
System.out.println(company);
}