在使用Spring Boot和OAuth2开发后端时,我偶然发现了相同的问题。我遇到的问题是,如果多个设备共享相同的令牌,则一台设备刷新令牌后,另一台设备将变得毫无头绪,长话短说,两台设备都进入了令牌刷新狂潮。我的解决方案是AuthenticationKeyGenerator
用自定义实现替换默认值,该实现DefaultAuthenticationKeyGenerator
将client_instance_id
在密钥生成器混合中覆盖并添加新参数。然后,我的移动客户端将发送此参数,该参数在应用程序安装(iOS或Android)中必须是唯一的。这不是特殊要求,因为大多数移动应用程序已经以某种形式跟踪了应用程序实例。
public class EnhancedAuthenticationKeyGenerator extends DefaultAuthenticationKeyGenerator {
public static final String PARAM_CLIENT_INSTANCE_ID = "client_instance_id";
private static final String KEY_SUPER_KEY = "super_key";
private static final String KEY_CLIENT_INSTANCE_ID = PARAM_CLIENT_INSTANCE_ID;
@Override
public String extractKey(final OAuth2Authentication authentication) {
final String superKey = super.extractKey(authentication);
final OAuth2Request authorizationRequest = authentication.getOAuth2Request();
final Map<String, String> requestParameters = authorizationRequest.getRequestParameters();
final String clientInstanceId = requestParameters != null ? requestParameters.get(PARAM_CLIENT_INSTANCE_ID) : null;
if (clientInstanceId == null || clientInstanceId.length() == 0) {
return superKey;
}
final Map<String, String> values = new LinkedHashMap<>(2);
values.put(KEY_SUPER_KEY, superKey);
values.put(KEY_CLIENT_INSTANCE_ID, clientInstanceId);
return generateKey(values);
}
}
然后您将以类似方式注入:
final JdbcTokenStore tokenStore = new JdbcTokenStore(mDataSource);
tokenStore.setAuthenticationKeyGenerator(new EnhancedAuthenticationKeyGenerator());
然后,HTTP请求将如下所示
POST /oauth/token HTTP/1.1
Host: {{host}}
Authorization: Basic {{auth_client_basic}}
Content-Type: application/x-www-form-urlencoded
grant_type=password&username={{username}}&password={{password}}&client_instance_id={{instance_id}}
使用此方法的好处是,如果客户端不发送client_instance_id
,则会生成默认密钥,并且如果提供了实例,则每次为同一实例返回相同的密钥。同样,关键是平台无关。不利的一面是MD5摘要(内部使用)被调用了两次。