справочная информация
Учетная запись может быть зарегистрирована только в одном месте, и подобные бизнес-требования очень распространены в существующих системах пост-управления. Но в исходном методе токена безопасности oauth2 Spring (так называемый вход в систему) не может удовлетворить аналогичные потребности.
давайте сначала посмотримTokenEndpoint
поток методов
Клиент обращается к интерфейсу /oauth/token с параметрами и, наконец, вызываетTokenGranter
TokenGranter
В соответствии с различными типами авторизации получите информацию об аутентификации пользователя и вызовитеTokenServices
сгенерировать токен
Re-TokenService
- Переписать логику релиза
createAccessToken
, когда токен, управляемый пользователем, существует, он будет удален и создан заново, что приведет к тому, что токен, полученный при предыдущем входе в систему, станет недействительным и будет выжат естественным образом.
@Transactional public OAuth2AccessToken createAccessToken() { OAuth2AccessToken existingAccessToken = tokenStore.getAccessToken(authentication); OAuth2RefreshToken refreshToken = null; // 重写此处,当用户关联的token 存在时,删除原有令牌 if (existingAccessToken != null) { tokenStore.removeAccessToken(existingAccessToken); } else if (refreshToken instanceof ExpiringOAuth2RefreshToken) { ExpiringOAuth2RefreshToken expiring = (ExpiringOAuth2RefreshToken) refreshToken; if (System.currentTimeMillis() > expiring.getExpiration().getTime()) { refreshToken = createRefreshToken(authentication); } }
скопировать кодOAuth2AccessToken accessToken = createAccessToken(authentication, refreshToken); tokenStore.storeAccessToken(accessToken, authentication); // In case it was modified refreshToken = accessToken.getRefreshToken(); if (refreshToken != null) { tokenStore.storeRefreshToken(refreshToken, authentication); } return accessToken; }
Переписать логику генерации ключа Token
- Как показано в приведенном выше коде, мы реализуем уникальный логин одного терминала пользователя. Что такое одиночный терминал? Мы можем использовать аналогию входа QQ. Мобильный терминал и терминал ПК могут войти в систему одновременно, но мобильный терминал и мобильный терминал не может одновременно находиться в сети.
- Как добиться уникального логина на разных клиентах?
Сначала посмотрите на исходный код вышеOAuth2AccessToken existingAccessToken=tokenStore.getAccessToken(authentication);
Как судить о существовании токена на основе информации о пользователе?
public OAuth2AccessToken getAccessToken(OAuth2Authentication authentication) { String key = authenticationKeyGenerator.extractKey(authentication); // redis 查询逻辑,根据 key return accessToken;
}
- Генератор значений ключа AuthenticationKeyGenerator по умолчанию в соответствии с
username
/clientId
/scope
Комбинация параметров генерирует уникальный токен
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);
}
- Если вы хотите реализовать уникальный логин нескольких терминалов, вам нужно только разрешить одному и тому же пользователю генерировать
token
Согласовано, плюс упомянутая выше логика модификации createToken, обе удаленыextractKey
Условие clientId для clientId не различает терминал
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());
}
if (authorizationRequest.getScope() != null) {
values.put(SCOPE, OAuth2Utils.formatParameterList(new TreeSet<String>(authorizationRequest.getScope())));
}
return generateKey(values);
}
- Наконец, добавьте новый TokenService на сервер авторизации.