我使用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;
}
}
}
问题是:
我可以通过&#34; authorization_code&#34;从spring zuul ui-server登录,并且可以 访问ResourceServer数据。
但是当access_token过期(120s)时,在重新获取ResourceServer数据时,我看到mongoTokenStore删除了现有的access_token,但是为什么不自动刷新新的access_token ?
如何解决?
答案 0 :(得分:0)
刷新令牌的重点是向OAuth2添加一个安全维度。
当最终用户获得访问令牌时,他现在可以访问令牌授予他的授权规则中的任何资源。
如果他的访问令牌以某种方式被盗,攻击者现在可以访问访问令牌授权他的任何资源,但是如果我们设置访问令牌的到期时间,则攻击者将具有有限的访问时间。
话虽如此,如果spring oauth2会自动刷新该令牌,那么将不再应用一个安全方面,并且整个令牌刷新的想法将被浪费。
因此,最后要确保您的最终用户再次通过OAuth2重新授权。
您还可以阅读: