Я натрапив на ту ж проблему, коли розробляв мітку з 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}}
Перевага використання цього підходу полягає в тому, що якщо клієнт не надсилає a client_instance_id
, буде створений ключ за замовчуванням, а якщо надається екземпляр, той самий ключ повертається кожен раз для одного і того ж екземпляра. Також ключ - незалежний від платформи. Мінусом було б те, що дайджест MD5 (використовується внутрішньо) викликається два рази.