У меня есть настройка весенней загрузки OAuth для AuthServer, и она отвечает за обслуживание нескольких серверов ресурсов для аутентификации с использованием spring-security-jwt.
Моя проблема заключается в том, что при аутентификации мне нужно загрузить роли пользователя, но специфичные для clientId.
например: если у пользователя1 есть роли ROLE_A, ROLE_B для клиента1 и ROLE_C, ROLE_D для клиента2, то когда пользователь входит в систему с использованием клиента1 или клиента2, он может видеть все четыре роли, т.е. ROLE_A, ROLE_B, ROLE_C, ROLE_D, потому что я получаю роли на основе имени пользователя.
Если мне нужна роль, основанная на клиенте, мне нужен clientId.
К вашему сведению,
Я использую поток кода авторизации для аутентификации.
Я видел аналогичный вопрос, но он основан на предоставлении пароля, но я пытаюсь использовать поток кода авторизации, и это решение не работает для меня.
Вопрос о предоставлении пароля связь
Ниже мой код, где мне нужен clientId
MyAuthenticationProvider.java
@Override
public Authentication authenticate(final Authentication authentication) throws AuthenticationException {
String userName = ((String) authentication.getPrincipal()).toLowerCase();
String password = (String) authentication.getCredentials();
String clientId = ? // how to get it
....
}
}
MyUserDetailsService.java
@Override
public UserDetails loadUserByUsername(String username) {
String clientId = ? // how to get it
....
}
}
Вероятно, вам нужно увидеть OAuth2Authentication в Spring-security. Когда ваш клиент аутентифицируется с помощью oauth2, ваша «аутентификация» на самом деле является экземпляром OAuth2Authentication, который в конечном итоге реализует аутентификацию.
Если вы видите реализацию OAuth2Authentication, это делается, как показано ниже;
public Object getPrincipal() {
return this.userAuthentication == null ? this.storedRequest.getClientId() : this.userAuthentication
.getPrincipal();
}
поэтому, если запрос включает «clientId», вы сможете получить clientId, вызвав getPrincipal() и приведя тип к String, если ваш запрос не включает аутентификацию пользователя.
Для вашего второго случая имя пользователя фактически считается идентификатором клиента. Вам нужно вызвать in-memory, RDBMS или любую другую реализацию, в которой хранится clientId и которая возвращает ClientDetails. Вы сможете получить некоторое представление, изучив класс Spring Security ClientDetailsUserDetailsService.
@AbidAli после того, как пользователь подписан, он прошел аутентификацию, теперь он может выполнять действия с клиентским приложением, вы можете создать RBAC для проверки ролей (т.е. вам нужно назначить роль с вашим приложением на сервере аутентификации, если он присутствует для принципа, т.е. текущего пользователя) Вы также должны предоставить такую роль серверу аутентификации. Так же, как и в службе OAuth, будет больше служб, которые выполняют только задачи RBAC.
Поскольку я не нашел подходящего решения для своего вопроса, я публикую решение, которое использовал после изучения исходного кода и исследований.
MyJwtAccessTokenConverter.java (расширить JwtAccessTokenConverter и внедрить метод улучшения)
public class OAuthServerJwtAccessTokenConverter extends JwtAccessTokenConverter {
....
@Override
public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
String clientId = authentication.getOAuth2Request().getClientId();
// principal can be string or UserDetails based on whether we are generating access token or refreshing access token
Object principal = authentication.getUserAuthentication().getPrincipal();
....
}
....
}
Информация:
В расширенном методе мы получим clientId из аутентификация.getOAuth2Request() и userDetails/user_name из аутентификация.getUserAuthentication().
Наряду с JwtAccessTokenConverter, AuthenticationProvider и UserDetailsService необходимы для проверки подлинности на этапе создания токена доступа и шаге обновления токена соответственно.
получить заголовок авторизации из запроса, а затем выполнить синтаксический анализ base64, чтобы получить идентификатор клиента.
что-то вроде этого:
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
.getRequestAttributes())
.getRequest();
String authHeader = request
.getHeader("Authorization");
Как я уже упоминал, грант — это код авторизации, т. е. в этом потоке я имею дело как с аутентификацией пользователя, так и с аутентификацией клиента. В моем случае MyAuthenticationProvider.java будет иметь дело только с аутентификацией пользователя, а не аутентификацией клиента, поэтому он не содержит OAuth2Authentication.