Как использовать клиент Spring Security OAuth 2, не используя его для входа/аутентификации

Я использую Spring Framework с Spring Security 5.7. Это относительно старый проект, написанный до весенней загрузки, поэтому я не использую какие-либо библиотеки или конфигурацию весенней загрузки.

У меня уже есть несколько способов аутентификации пользователя на моем сервере, через имя пользователя/пароль, SSO через Google, Microsoft и т. д.

Я пытаюсь использовать клиент Spring Security OAuth2 для аутентификации уже вошедшего в систему пользователя с помощью сторонней службы, поэтому я, в свою очередь, могу выполнять API-вызовы этой службы от имени пользователя.

Приложение также достаточно старое, поэтому я использую конфигурацию XML для своей весенней конфигурации безопасности, и у меня есть несколько тегов области, настроенных для разных целей безопасности/аутентификации/авторизации. Тем не менее, мы постепенно переводим нашу конфигурацию с xml на java и предпочли бы настроить как можно больше в java, если это возможно.

На данный момент, вот моя конфигурация Java:

@Configuration
public class OAuthConfig {

@Bean
public ClientRegistrationRepository clientRegistrationRepository() {
    
    List<ClientRegistration> registrations = new ArrayList<>(1);
    
    ClientRegistration client = ClientRegistration.withRegistrationId("blarg")
            /* omitted client details here */
            .redirectUri("https://example.com/oauth/blarg")
            .build();
    
    registrations.add(client);
    
    return new InMemoryClientRegistrationRepository(registrations);
}

@Bean
public OAuth2AuthorizedClientService authorizedClientService(ClientRegistrationRepository repository) {
    return new InMemoryOAuth2AuthorizedClientService(repository);
}

@Bean
public OAuth2AuthorizedClientRepository authorizedClientRepository(OAuth2AuthorizedClientService service) {
    return new AuthenticatedPrincipalOAuth2AuthorizedClientRepository(service);
}

@Bean
public OAuth2AuthorizedClientManager authorizedClientManager(
        ClientRegistrationRepository clientRegistrationRepository,
        OAuth2AuthorizedClientRepository authorizedClientRepository) {
    
    OAuth2AuthorizedClientProvider provider = OAuth2AuthorizedClientProviderBuilder.builder()
            .authorizationCode()
            .build();
    
    DefaultOAuth2AuthorizedClientManager manager = new DefaultOAuth2AuthorizedClientManager(
            clientRegistrationRepository, authorizedClientRepository);
    manager.setAuthorizedClientProvider(provider);
    
    return manager;
}

@Bean
public AuthorizationRequestRepository<OAuth2AuthorizationRequest> authorizationRequestRepository() {
    return new HttpSessionOAuth2AuthorizationRequestRepository();
}

Кроме того, я добавил фильтр в свою основную область безопасности в xml:

applicationContext-web-security.xml:

...
<bean id = "oAuth2AuthorizationRequestRedirectFilter" 
        class = "org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter">
    <constructor-arg ref = "clientRegistrationRepository"/>
    <constructor-arg value = "/oauth/authorization"/>
</bean>

<security:http auto-config = "false" use-expressions = "true" disable-url-rewriting = "true">
    ...
    <security:custom-filter ref = "oAuth2AuthorizationRequestRedirectFilter" position = "OAUTH2_AUTHORIZATION_REQUEST_FILTER"/>
    ...
</security:http>

Я, очевидно, опускаю большую часть своей конфигурации, но это новые вещи, связанные конкретно с клиентом oauth2.

На данный момент я перенаправляю своего клиента на /oauth/authorization/blaRG, чтобы запустить поток OAuth 2. Это правильно обрабатывается RedirectFilter для перенаправления третьей стороны для входа и авторизации. У меня есть проблема: как мне обработать ответ, который будет отправлен на https://example.com:9000/oauth/blarg? Он должен содержать код авторизации, который я должен преобразовать в accessToken и сохранить результат в authorClientRepository. Я знаю, как использовать репозиторий с этого момента, но я не знаю, как перейти от получения обратного вызова с кодом авторизации к получению токена доступа. В документации упоминается OAuth2AccessTokenResponseClient, но на самом деле не говорится, как его использовать.

Я даже не уверен, что мое ручное перенаправление на /oauth/authorization/blarg является правильным способом запуска потока.

Многое из того, что я нахожу в Интернете, связано со старым материалом Spring Security OAuth или связано с использованием oauth для входа пользователя через SSO.

Пожалуйста, не просто дайте мне ссылку на документацию Spring Security OAuth2 Client или javadocs, так как я просматриваю их снова и снова в течение достаточно долгого времени.

Спасибо за любую помощь, которую вы можете предоставить!

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
287
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это то, что я наконец придумал. Все еще используя конфигурацию Java из приведенного выше, вот как выглядит моя конфигурация XML. Я знаю, что могу переместить некоторые из этих bean-компонентов в конфигурацию Java, но части все еще работают.

В основном я создаю и RedirectFilter, и AuthorizationCodeGrantFilter, но GrantFilter нужен диспетчер аутентификации с провайдером, который знает, как обменять код авторизации на токен доступа, что и делает провайдер аутентификации.

    <bean id = "authorizationCodeTokenResponseClient"
        class = "org.springframework.security.oauth2.client.endpoint.DefaultAuthorizationCodeTokenResponseClient"/>

<bean id = "oAuth2AuthorizationCodeAuthenticationProvider" 
        class = "org.springframework.security.oauth2.client.authentication.OAuth2AuthorizationCodeAuthenticationProvider">
        <constructor-arg ref = "authorizationCodeTokenResponseClient"/>
</bean>

<bean id = "oAuthAuthenticationManager" class = "org.springframework.security.authentication.ProviderManager">
    <constructor-arg name = "providers">
        <list>
            <ref bean = "oAuth2AuthorizationCodeAuthenticationProvider"/>
        </list>
    </constructor-arg>
</bean>    

<bean id = "oAuth2AuthorizationRequestRedirectFilter" 
        class = "org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter">
        <constructor-arg ref = "clientRegistrationRepository"/>
        <constructor-arg value = "/oauth/authorization"/>
</bean>

<bean id = "oAuth2AuthorizationCodeGrantFilter" 
        class = "org.springframework.security.oauth2.client.web.BulbGrantFilter">
        <constructor-arg ref = "clientRegistrationRepository"/>
        <constructor-arg ref = "authorizedClientRepository"/>
        <constructor-arg ref = "oAuthAuthenticationManager"/>
</bean>

Затем в моем теге http я добавляю оба фильтра в стандартную цепочку:

<secuirty:http ...>
    ...
    <security:custom-filter ref = "oAuth2AuthorizationRequestRedirectFilter" 
            position = "OAUTH2_AUTHORIZATION_REQUEST_FILTER"/>
    <security:custom-filter ref = "oAuth2AuthorizationCodeGrantFilter" 
            position = "OAUTH2_AUTHORIZATION_CODE_GRANT_FILTER"/>
    ...
</security:http>

Когда я хочу, чтобы пользователь авторизовал стороннюю службу, я перенаправляю их на /oauth/authorization/blaRG, который перехватывается requestFilter, который использует настроенную информацию о клиенте blarg для перенаправления пользователя третьей стороне для входа/авторизации. мое приложение. Сторонняя сторона перенаправляет обратно в мое приложение, и GrantFilter достаточно умен, чтобы сказать, что это ответ кода авторизации. Этот фильтр принимает код аутентификации и использует поставщика аутентификации для его проверки и обмена на маркер доступа и маркер обновления, а затем сохраняет их в authorClientRepository.

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