Spring Security Oauth2手动生成OAuth2AccessToken(十二)

如果接入多种登录方式,如:平台用户名密码登录、手机验证码登录,第三方登录(微信、QQ)。可以在验证通过之后在 AuthenticationSuccessHandler 中 通过 Authentication 生成手动生成token。

  • TokenGenerator.java
@Component
public class TokenGenerator {

    @Autowired
    @Qualifier("tokenServices")
    private AuthorizationServerTokenServices authorizationServerTokenServices;

    @Autowired
    private ClientDetailsService clientDetailsService;

    @Autowired
    private TokenStore tokenStore;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    private static final String ACCESS_TO_REFRESH = "access_to_refresh:";

    /**
     * 表单验证完成后创建token
     * @param authentication
     * @return
     */
    public OAuth2AccessToken createToken(Authentication authentication) {
        ClientDetails clientDetails = clientDetailsService.loadClientByClientId("c");
        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = (UsernamePasswordAuthenticationToken) authentication;

        TokenRequest tokenRequest = tokenRequest();

        OAuth2Request oAuth2Request = tokenRequest.createOAuth2Request(clientDetails);

        OAuth2Authentication oAuth2Authentication = new OAuth2Authentication(oAuth2Request, usernamePasswordAuthenticationToken);

        OAuth2AccessToken token = authorizationServerTokenServices.createAccessToken(oAuth2Authentication);

        return token;
    }

    /**
     * 刷新token
     * @param accessToken
     * @return
     */
    public OAuth2AccessToken refresh(String accessToken) {
        OAuth2AccessToken _accessToken = tokenStore.readAccessToken(accessToken);
        if (Objects.nonNull(_accessToken) && !_accessToken.isExpired()) {
            return _accessToken;
        }

        String refreshToken = stringRedisTemplate.opsForValue().get(ACCESS_TO_REFRESH + accessToken);
        return authorizationServerTokenServices.refreshAccessToken(refreshToken, tokenRequest());
    }


    private TokenRequest tokenRequest() {
        ClientDetails clientDetails = clientDetailsService.loadClientByClientId("c");

        TokenRequest tokenRequest = new TokenRequest(Collections.emptyMap(),
                clientDetails.getClientId(),
                clientDetails.getScope(),
                "all");

        return tokenRequest;
    }
}
  • 测试
@SpringBootTest
public class TokenGeneratorTest {

    @Autowired
    private TokenGenerator tokenGenerator;

    @Test
    public void testCreateToken() {
        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken
                = new UsernamePasswordAuthenticationToken("rick", "123456"
                , AuthorityUtils.commaSeparatedStringToAuthorityList("ADMIN, p1, p2"));
        OAuth2AccessToken token = tokenGenerator.createToken(usernamePasswordAuthenticationToken);
        System.out.println(token.getExpiration());
        System.out.println(token);
    }

    @Test
    public void testRefresh() {
        String accessToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsicmVzIl0sInVzZXJfbmFtZSI6InJpY2siLCJzY29wZSI6WyJhbGwiXSwiaGVsbG8iOiJ3b3JsZCIsImV4cCI6MTYzNDMwMjkyNCwiYXV0aG9yaXRpZXMiOlsicDEiLCJwMiIsIkFETUlOIl0sImp0aSI6Ik5HZ0hEYUZiZFdXeWEyTUN1ZDFGZ0N5T1gyRSIsImNsaWVudF9pZCI6ImMifQ.X0Y9jXHD4u9aszh9lXs0flnyuNBm3lJ2Swiy49TxSqw";
        OAuth2AccessToken token = tokenGenerator.refresh(accessToken);
        System.out.println(token.getValue().equals(accessToken));
    }
}