Spring OAuth2.0: получение ролей пользователей на основе ClientId (тип предоставления кода авторизации)

У меня есть настройка весенней загрузки 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 
        ....
    }
}
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Версия Java на основе версии загрузки
Версия Java на основе версии загрузки
Если вы зайдете на официальный сайт Spring Boot , там представлен start.spring.io , который упрощает создание проектов Spring Boot, как показано ниже.
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
0
0
1 397
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вероятно, вам нужно увидеть 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.

Как я уже упоминал, грант — это код авторизации, т. е. в этом потоке я имею дело как с аутентификацией пользователя, так и с аутентификацией клиента. В моем случае MyAuthenticationProvider.java будет иметь дело только с аутентификацией пользователя, а не аутентификацией клиента, поэтому он не содержит OAuth2Authentication.

Abid Ali 31.05.2019 05:50

@AbidAli после того, как пользователь подписан, он прошел аутентификацию, теперь он может выполнять действия с клиентским приложением, вы можете создать RBAC для проверки ролей (т.е. вам нужно назначить роль с вашим приложением на сервере аутентификации, если он присутствует для принципа, т.е. текущего пользователя) Вы также должны предоставить такую ​​роль серверу аутентификации. Так же, как и в службе OAuth, будет больше служб, которые выполняют только задачи RBAC.

Ashish Kamble 27.01.2020 13:10
Ответ принят как подходящий

Поскольку я не нашел подходящего решения для своего вопроса, я публикую решение, которое использовал после изучения исходного кода и исследований.
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");

Другие вопросы по теме