我使用 mongo 自定义 tokenStore 和 codeService:
这是我的自定义 mongoTokenStore:
public class MongoTokenStore implements TokenStore {
private final MongoAccessTokenRepository mongoAccessTokenRepository;
private final MongoRefreshTokenRepository mongoRefreshTokenRepository;
private AuthenticationKeyGenerator authenticationKeyGenerator =
new DefaultAuthenticationKeyGenerator();
public MongoTokenStore(MongoAccessTokenRepository mongoAccessTokenRepository, MongoRefreshTokenRepository mongoRefreshTokenRepository) {
this.mongoAccessTokenRepository = mongoAccessTokenRepository;
this.mongoRefreshTokenRepository = mongoRefreshTokenRepository;
}
@Override
public OAuth2Authentication readAuthentication(OAuth2AccessToken oAuth2AccessToken) {
return readAuthentication(oAuth2AccessToken.getValue());
}
@Override
public OAuth2Authentication readAuthentication(String tokenId) {
return mongoAccessTokenRepository.findByTokenId(tokenId)
.map(MongoAccessToken::getAuthentication)
.orElse(null);
}
@Override
public void storeAccessToken(OAuth2AccessToken oAuth2AccessToken, OAuth2Authentication oAuth2Authentication) {
MongoAccessToken mongoAccessToken = new MongoAccessToken(oAuth2AccessToken, oAuth2Authentication,
authenticationKeyGenerator.extractKey(oAuth2Authentication));
mongoAccessTokenRepository.save(mongoAccessToken);
}
@Override
public OAuth2AccessToken readAccessToken(String tokenValue) {
return mongoAccessTokenRepository.findByTokenId(tokenValue)
.map(MongoAccessToken::getOAuth2AccessToken)
.orElse(null);
}
@Override
public void removeAccessToken(OAuth2AccessToken oAuth2AccessToken) {
mongoAccessTokenRepository.findByTokenId(oAuth2AccessToken.getValue())
.ifPresent(mongoAccessTokenRepository::delete);
}
@Override
public void storeRefreshToken(OAuth2RefreshToken oAuth2RefreshToken, OAuth2Authentication oAuth2Authentication) {
MongoRefreshToken token=new MongoRefreshToken(oAuth2RefreshToken,oAuth2Authentication);
mongoRefreshTokenRepository.save(token);
}
@Override
public OAuth2RefreshToken readRefreshToken(String tokenValue) {
return mongoRefreshTokenRepository.findByTokenId(tokenValue)
.map(MongoRefreshToken::getOAuth2RefreshToken)
.orElse(null);
}
@Override
public OAuth2Authentication readAuthenticationForRefreshToken(OAuth2RefreshToken oAuth2RefreshToken) {
return mongoRefreshTokenRepository.findByTokenId(oAuth2RefreshToken.getValue())
.map(MongoRefreshToken::getAuthentication)
.orElse(null);
}
@Override
public void removeRefreshToken(OAuth2RefreshToken oAuth2RefreshToken) {
mongoRefreshTokenRepository.findByTokenId(oAuth2RefreshToken.getValue())
.ifPresent(mongoRefreshTokenRepository::delete);
}
@Override
public void removeAccessTokenUsingRefreshToken(OAuth2RefreshToken oAuth2RefreshToken) {
mongoAccessTokenRepository.findByRefreshToken(oAuth2RefreshToken.getValue())
.ifPresent(mongoAccessTokenRepository::delete);
}
@Override
public OAuth2AccessToken getAccessToken(OAuth2Authentication oAuth2Authentication) {
return mongoAccessTokenRepository.findByAuthenticationId(authenticationKeyGenerator
.extractKey(oAuth2Authentication))
.map(MongoAccessToken::getOAuth2AccessToken)
.orElse(null);
}
@Override
public Collection<OAuth2AccessToken> findTokensByClientIdAndUserName(String s, String s1) {
return mongoAccessTokenRepository.findByClientIdAndUserName(s,s1)
.stream()
.map(MongoAccessToken::getOAuth2AccessToken)
.collect(Collectors.toList());
}
@Override
public Collection<OAuth2AccessToken> findTokensByClientId(String s) {
return mongoAccessTokenRepository.findByClientId(s)
.stream()
.map(MongoAccessToken::getOAuth2AccessToken)
.collect(Collectors.toList());
}
}
这是我的自定义 mongoCodeService:
@Component
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class MongoAuthenticationCodeService extends RandomValueAuthorizationCodeServices{
private final MongoAuthenticationCodeRepository repository;
@Override
protected void store(String code, OAuth2Authentication oAuth2Authentication) {
repository.save(new MongoAuthenticationCode(code,oAuth2Authentication));
}
@Override
protected OAuth2Authentication remove(String code) {
return repository.findOneByCode(code)
.map(MongoAuthenticationCode::getAuthentication)
.orElse(null);
}
}
和我的 OAuth2Config:
@Configuration
public class OAuth2ServerConfiguration {
@Configuration
@EnableResourceServer
protected static class ResourceServerConfiguration extends
ResourceServerConfigurerAdapter {
@Override
public void configure(ResourceServerSecurityConfigurer resources) {
resources.resourceId(READ_AND_WRITE_RESOURCE_ID);
}
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/webjars/**", "/oauth/authorize/**", "/", "/customLogout",
"/oauth/check_token/**", "/login").permitAll()
.mvcMatchers(HttpMethod.GET, "/loginAttemptUsers").hasRole("ADMIN")
.anyRequest().authenticated();
}
}
@Configuration
@EnableAuthorizationServer
protected static class AuthorizationServerConfiguration extends
AuthorizationServerConfigurerAdapter {
@Autowired
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
@Autowired
private CustomUserDetailService customUserDetailService;
@Autowired
private MongoAuthenticationCodeService mongoAuthenticationCodeService;
@Autowired
private MongoTokenStore mongoTokenStore;
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints)
throws Exception {
endpoints
.authorizationCodeServices(mongoAuthenticationCodeService)
.tokenStore(mongoTokenStore)
.authenticationManager(authenticationManager)
.userDetailsService(customUserDetailService)
.approvalStoreDisabled();
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients
.inMemory()
.withClient("kksdi2388wmkwe")
.authorizedGrantTypes("authorization_code", "password", "refresh_token")
.scopes("read", "write")
.resourceIds("ReadAndWriteResource")
.secret("kksd23isdmsisdi2")
.autoApprove(true)
.accessTokenValiditySeconds(120)
.refreshTokenValiditySeconds(1200);
}
@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer
.tokenKeyAccess("permitAll()")
.checkTokenAccess("isAuthenticated()");
}
@Bean
@Primary
public DefaultTokenServices tokenServices() {
DefaultTokenServices tokenServices = new DefaultTokenServices();
tokenServices.setSupportRefreshToken(true);
tokenServices.setTokenStore(tokenStore);
return tokenServices;
}
}
}
问题是:
我可以通过“authorization_code”从 spring zuul ui-server 登录,并且可以访问 ResourceServer 数据。
但是当 access_token 过期(120s)时,在重新获取 ResourceServer 数据时,我看到 mongoTokenStore 删除了现有的 access_token ,但为什么不自动刷新新的 access_token?
如何解决?