springboot-OAuth2-jwt

springboot OAuth2 jwt的几个问题及解决

首先说明自己的问题, 基本的集成的话可以参考其他的博文
一. 在jwt的payload中加入自定义的一些信息 网上的看到很多是通过TokenEhancer添加, 跟踪源码后发现添加不进去;
二. jwt的过期时间设置
对于第一个问题:在jwt的payload中加入自定义的一些信息
有2个解决方案,
1.1一个是原始的解决方案, 我是直接重写了DefaultUserAuthenticationConverter的convertUserAuthentication()方法

package com.gee.spring.boot.oauth2.auth.config.oauth2.token;

import com.gee.spring.boot.oauth2.auth.entity.AuthUser;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.oauth2.provider.token.DefaultUserAuthenticationConverter;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * desc:
 *
 * @author gee
 * @date 2020/04/06 18:26
 */
public class GeeUserAuthenticationConverter extends DefaultUserAuthenticationConverter {
    @Override
    public Map<String, ?> convertUserAuthentication(Authentication authentication) {
        AuthUser authUser = (AuthUser)authentication.getPrincipal();
        Map<String, Object> response = new LinkedHashMap<>();
        response.put("user_name", authUser.getUsername());
        response.put("user_id", authUser.getId());
        if (authentication.getAuthorities() != null && !authentication.getAuthorities().isEmpty()) {
            response.put("authorities", AuthorityUtils.authorityListToSet(authentication.getAuthorities()));
        }
        return response;
    }
}

然后在token的配置中,将自己的GeeUserAuthenticationConverter 设置在JwtAccessTokenConverter中

/**
 * desc:
 *
 * @author gee
 * @date 2020/04/06 16:27
 */
@Configuration
public class TokenConfig {

    @Bean(value = "jwtTokenStore")
    public JwtTokenStore jwtTokenStore(){
        return new JwtTokenStore(jwtAccessTokenConverter());
    }

    @Bean
    public JwtAccessTokenConverter jwtAccessTokenConverter(){
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        converter.setAccessTokenConverter(geeAccessTokenConverter());
        converter.setSigningKey(OauthConstant.OAUTH2_JWT_SIGN_KEY);
        return converter;
    }

    private GeeAccessTokenConverter geeAccessTokenConverter(){
        GeeAccessTokenConverter accessTokenConverter = new GeeAccessTokenConverter();
        //如果要实现往jwt的payload里添加信息, 要设置UserAuthenticationConverter的实现类
        GeeUserAuthenticationConverter userAuthenticationConverter = new GeeUserAuthenticationConverter();
        accessTokenConverter.setUserTokenConverter(userAuthenticationConverter);
        return accessTokenConverter;
    }
}

然后Oauth2OuthorizationConig的配置基本没什么区别,这里也直接贴出来

/**
 * desc:
 *
 * @author gee
 * @date 2020/04/06 16:29
 */
@Configuration
@EnableAuthorizationServer
public class Oauth2AuthorizationConfig extends AuthorizationServerConfigurerAdapter {

    @Resource
    private DataSource dataSource;

    @Resource
    private AuthenticationManager authenticationManager;

    @Resource
    private JwtTokenStore jwtTokenStore;

    @Resource
    private JwtAccessTokenConverter jwtAccessTokenConverter;

    private ClientDetailsService clientDetailsService(){
        return new JdbcClientDetailsService(dataSource);
    }

    @Bean
    public AuthorizationCodeServices authorizationCodeServices(){
        return new JdbcAuthorizationCodeServices(dataSource);
    }

    private DefaultTokenServices tokenServices(){
        DefaultTokenServices tokenServices = new DefaultTokenServices();
        tokenServices.setTokenStore(jwtTokenStore);
        tokenServices.setTokenEnhancer(tokenEnhancerChain());
        tokenServices.setClientDetailsService(clientDetailsService());
        tokenServices.setSupportRefreshToken(true);
        //如果在client的配置中 已经设置了token/refreshToken的过期时间的话, tokenServices中设置的过期时间无效
        tokenServices.setAccessTokenValiditySeconds(15*60);
        tokenServices.setRefreshTokenValiditySeconds(7*24*60*60);
        return tokenServices;
    }

    private TokenEnhancerChain tokenEnhancerChain(){
        TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
        tokenEnhancerChain.setTokenEnhancers(Collections.singletonList(jwtAccessTokenConverter));
        return tokenEnhancerChain;
    }

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security){
        security.allowFormAuthenticationForClients()
                .checkTokenAccess("isAuthenticated()");
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.withClientDetails(clientDetailsService());
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
        endpoints.authenticationManager(authenticationManager)
                .authorizationCodeServices(authorizationCodeServices())
                .tokenServices(tokenServices())
                ;
    }

}

1.2第二种比较简单的处理,就是在UserDetailsService.loadUserByUsername()方法将username直接设置成包含需要添加信息的json字符串,属于比较偷懒的写法.

@Service
public class GeeUserDetailServiceImpl implements UserDetailsService {

    @Autowired
    private UserService userService;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        User user = userService.getByUserName(username);
        if (user == null){
            return null;
        }
        Set<GrantedAuthority> authorities = new HashSet<>();
        authorities.add(new SimpleGrantedAuthority("1"));
        return new org.springframework.security.core.userdetails.User(Json.toString(user),user.getPassword(),authorities);
    }

}

2.针对第二个问题, oauth2的配置类中也注释了,
如果在client的配置中 已经设置了token/refreshToken的过期时间的话, tokenServices中设置的过期时间无效
所以jwt中的过期时间会跟client中过期时间保持一致,本用例中是在数据库中配置.
lhttps://gitee.com/gepengjun/springboot-oauth2-jwt.

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值