一.SpringSecurityOAuth简介

spring security logout有时403 spring security oauth jwt_ide


grant_type为授权模式password为密码模式

@EnableAuthorizationServer表示定义认证服务器

@EnableResourceServer表示定义资源服务器

spring security logout有时403 spring security oauth jwt_Jwt_02

二.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);
}