oauth 2.0 服务端可以参考文章: Spring Security oauth2.0 服务端
默认情况下,通过相同的参数请求 /oauth/token 接口,返回的 access_token 是同一个 token,而 expires_in 会减少,expires_in 是 token 的有效期,单位为秒

很多场景,都需要我们每次请求都返回一个新的 token,那么如何实现呢,下面先了解一下 DefaultAuthenticationKeyGenerator
- 默认的身份验证密钥生成器
- 根据 client id、scope、username 生成
- authentication.isClientOnly():判断 grant_type 是否 client_credentials 模式
public String extractKey(OAuth2Authentication authentication) {
Map<String, String> values = new LinkedHashMap<String, String>();
OAuth2Request authorizationRequest = authentication.getOAuth2Request();
if (!authentication.isClientOnly()) {
values.put(USERNAME, authentication.getName());
}
values.put(CLIENT_ID, authorizationRequest.getClientId());
if (authorizationRequest.getScope() != null) {
values.put(SCOPE, OAuth2Utils.formatParameterList(new TreeSet<String>(authorizationRequest.getScope())));
}
return generateKey(values);
}
很容易看出,只要 values 不相同,那么生成的 token 就不相同
那么思路来了
- 新增 AuthenticationKeyGenerator 继承 DefaultAuthenticationKeyGenerator
- 重新 extractKey() 方法
- values 添加永远不重复的 CODE
- 把 AuthenticationKeyGenerator 添加到 TokenStore
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
...
private class AuthenticationKeyGenerator extends DefaultAuthenticationKeyGenerator {
private static final String CLIENT_ID = "client_id";
private static final String SCOPE = "scope";
private static final String USERNAME = "username";
private static final String CODE = "code";
@Override
public String extractKey(OAuth2Authentication authentication) {
Map<String, String> values = new LinkedHashMap<String, String>();
OAuth2Request authorizationRequest = authentication.getOAuth2Request();
if (!authentication.isClientOnly()) {
values.put(USERNAME, authentication.getName());
}
values.put(CLIENT_ID, authorizationRequest.getClientId());
if (authorizationRequest.getScope() != null) {
values.put(SCOPE, OAuth2Utils.formatParameterList(new TreeSet<String>(authorizationRequest.getScope())));
}
UUID uuid4 = UUID.randomUUID();
values.put(CODE, uuid4.toString());
return generateKey(values);
}
}
@Bean
public TokenStore tokenStore() {
InMemoryTokenStore tokenStore = new InMemoryTokenStore();
tokenStore.setAuthenticationKeyGenerator(new AuthenticationKeyGenerator());
return tokenStore;
}
...
}
|