Tôi đã vấp phải vấn đề tương tự trong khi phát triển phần phụ trợ của mình với Spring Boot và OAuth2. Vấn đề tôi gặp phải là, nếu nhiều thiết bị chia sẻ cùng một mã thông báo, một khi một thiết bị làm mới mã thông báo, thiết bị kia sẽ không biết gì và, câu chuyện dài, cả hai thiết bị được nhập vào mã thông báo làm mới điên cuồng. Giải pháp của tôi là thay thế mặc định AuthenticationKeyGenerator
bằng một triển khai tùy chỉnh ghi đè DefaultAuthenticationKeyGenerator
và thêm một tham số mới client_instance_id
trong hỗn hợp trình tạo khóa. Các khách hàng di động của tôi sau đó sẽ gửi tham số này phải là duy nhất trên các cài đặt ứng dụng (iOS hoặc Android). Đây không phải là một yêu cầu đặc biệt, vì hầu hết các ứng dụng di động đã theo dõi trường hợp ứng dụng ở một số dạng.
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);
}
}
mà sau đó bạn sẽ tiêm theo cách tương tự:
final JdbcTokenStore tokenStore = new JdbcTokenStore(mDataSource);
tokenStore.setAuthenticationKeyGenerator(new EnhancedAuthenticationKeyGenerator());
Yêu cầu HTTP sau đó sẽ trông giống như thế này
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}}
Lợi ích của việc sử dụng phương pháp này là, nếu máy khách không gửi client_instance_id
, khóa mặc định sẽ được tạo và nếu một thể hiện được cung cấp, cùng một khóa được trả về mỗi lần cho cùng một thể hiện. Ngoài ra, chìa khóa là nền tảng độc lập. Nhược điểm sẽ là thông báo MD5 (được sử dụng nội bộ) được gọi hai lần.