Почему я получаю неправильный ответ токена при обмене кода авторизации на токен доступа? (пружинный башмак, oauth2, azure) - PullRequest
1 голос
/ 19 февраля 2020

Я добавляю oauth в приложение и сталкиваюсь со следующей ошибкой:

[invalid_token_response] An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: 401 Unauthorized: [no body]

Проект имеет бэкэнд Spring Boot и интерфейс Eclipse rcp. Я пытаюсь аутентифицироваться, используя azure активный каталог в качестве сервера авторизации. Пока что я могу запустить виджет браузера при запуске приложения eclipse и успешно выполнить запрос кода авторизации, указав браузеру http://localhost: 8080 / oauth2 / authorization / azure , После завершения запроса кода авторизации браузер перенаправляется на http://localhost: 8080 / login? Error и отображает вышеуказанную ошибку.

Зависимости от pom. xml

Построен с использованием пружинной загрузки со следующими соответствующими зависимостями:

  • spring-boot-starter-web v2.2.4
  • azure-active-directory-spring-boot-starter v2.2.1
  • spring-security-oauth2-client v5. 2.1
  • spring-security-oauth2-jose v5.2.1
  • spring-security-oauth2-resource-server v5.2.1

Конфигурация из application.yml

Мы поддерживаем несколько серверов авторизации Вот полностью настроенный клиент azure:

spring:
  security:
    oauth2:
      client:
        azure:
          client-id: XXX
          client-secret: XXX
          client-name: Microsoft
          scope: openid, https://graph.microsoft.com/user.read, profile
          authorization-grant-type: authorization_code
          redirect-uri: http://localhost:8080/login/oauth2/code/azure
          client-authentication-method: basic
          authentication-method: post
      provider:
        authorization-uri: https://login.microsoftonline.com/XXX/oauth2/v2.0/authorize
        token-uri: https://login.microsoftonline.com/XXX/oauth2/v2.0/token
        user-info-uri: https://graph.microsoft.com/oidc/userinfo
        jwt-set-uri: https://login.microsoftonline.com/dXXX/discovery/v2.0/keys

azure:
   activedirectory:
      tenant-id: XXX
      active-directory-groups: XXX
      allow-telemetry: false

websecurityconfig. java

@Configuration
@EnableConfigurationProperties
@EnableWebSecurity
@Order(1)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .authorizeRequests()
                    [...]
                    .anyRequest().authenticated()
                    .and()
                .oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt)
                .oauth2Login();
    }

    [...]
}

Журналы Spring

Вот полная трассировка стека от В тот момент, когда я пытаюсь пройти аутентификацию с помощью моих azure учетных данных пользователя AD (сокращено в соответствии с требованиями к длине тела и с кодом авторизации, проверенным на c):

2020-02-19 16:10:33.925 DEBUG 19564 --- [qtp148813381-16] o.s.s.w.header.writers.HstsHeaderWriter  : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@2dd6e039
2020-02-19 16:10:33.925 DEBUG 19564 --- [qtp148813381-16] w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2020-02-19 16:10:33.925 DEBUG 19564 --- [qtp148813381-16] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
2020-02-19 16:10:33.928 DEBUG 19564 --- [qtp148813381-20] o.s.security.web.FilterChainProxy        : /login/oauth2/code/azure?code=CODE&state=nqsFqxkkNzHJE5knQVdqFLjoPxg1MT_bcn7KzjKSFfU%3d&session_state=3ebe517e-d450-4d49-b8db-8afafe1fa37e at position 1 of 16 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2020-02-19 16:10:33.929 DEBUG 19564 --- [qtp148813381-20] o.s.security.web.FilterChainProxy        : /login/oauth2/code/azure?code=CODE&state=nqsFqxkkNzHJE5knQVdqFLjoPxg1MT_bcn7KzjKSFfU%3d&session_state=3ebe517e-d450-4d49-b8db-8afafe1fa37e at position 2 of 16 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2020-02-19 16:10:33.929 DEBUG 19564 --- [qtp148813381-20] w.c.HttpSessionSecurityContextRepository : HttpSession returned null object for SPRING_SECURITY_CONTEXT
2020-02-19 16:10:33.929 DEBUG 19564 --- [qtp148813381-20] w.c.HttpSessionSecurityContextRepository : No SecurityContext was available from the HttpSession: Session@3a690b15{id=node01xqnw7l82ne041bil2flqsn3vr0,x=node01xqnw7l82ne041bil2flqsn3vr0.node0,req=1,res=true}. A new one will be created.
2020-02-19 16:10:33.929 DEBUG 19564 --- [qtp148813381-20] o.s.security.web.FilterChainProxy        : /login/oauth2/code/azure?code=CODE&state=nqsFqxkkNzHJE5knQVdqFLjoPxg1MT_bcn7KzjKSFfU%3d&session_state=3ebe517e-d450-4d49-b8db-8afafe1fa37e at position 3 of 16 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2020-02-19 16:10:33.929 DEBUG 19564 --- [qtp148813381-20] o.s.security.web.FilterChainProxy        : /login/oauth2/code/azure?code=CODE&state=nqsFqxkkNzHJE5knQVdqFLjoPxg1MT_bcn7KzjKSFfU%3d&session_state=3ebe517e-d450-4d49-b8db-8afafe1fa37e at position 4 of 16 in additional filter chain; firing Filter: 'LogoutFilter'
2020-02-19 16:10:33.929 DEBUG 19564 --- [qtp148813381-20] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/logout', GET]
2020-02-19 16:10:33.929 DEBUG 19564 --- [qtp148813381-20] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login/oauth2/code/azure'; against '/logout'
2020-02-19 16:10:33.929 DEBUG 19564 --- [qtp148813381-20] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/logout', POST]
2020-02-19 16:10:33.929 DEBUG 19564 --- [qtp148813381-20] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request 'GET /login/oauth2/code/azure' doesn't match 'POST /logout'
2020-02-19 16:10:33.929 DEBUG 19564 --- [qtp148813381-20] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/logout', PUT]
2020-02-19 16:10:33.929 DEBUG 19564 --- [qtp148813381-20] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request 'GET /login/oauth2/code/azure' doesn't match 'PUT /logout'
2020-02-19 16:10:33.929 DEBUG 19564 --- [qtp148813381-20] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/logout', DELETE]
2020-02-19 16:10:33.929 DEBUG 19564 --- [qtp148813381-20] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request 'GET /login/oauth2/code/azure' doesn't match 'DELETE /logout'
2020-02-19 16:10:33.929 DEBUG 19564 --- [qtp148813381-20] o.s.s.web.util.matcher.OrRequestMatcher  : No matches found
2020-02-19 16:10:33.929 DEBUG 19564 --- [qtp148813381-20] o.s.security.web.FilterChainProxy        : /login/oauth2/code/azure?code=CODE&state=nqsFqxkkNzHJE5knQVdqFLjoPxg1MT_bcn7KzjKSFfU%3d&session_state=3ebe517e-d450-4d49-b8db-8afafe1fa37e at position 5 of 16 in additional filter chain; firing Filter: 'OAuth2AuthorizationRequestRedirectFilter'
2020-02-19 16:10:33.930 DEBUG 19564 --- [qtp148813381-20] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login/oauth2/code/azure'; against '/oauth2/authorization/{registrationId}'
2020-02-19 16:10:33.930 DEBUG 19564 --- [qtp148813381-20] o.s.security.web.FilterChainProxy        : /login/oauth2/code/azure?code=CODE&state=nqsFqxkkNzHJE5knQVdqFLjoPxg1MT_bcn7KzjKSFfU%3d&session_state=3ebe517e-d450-4d49-b8db-8afafe1fa37e at position 6 of 16 in additional filter chain; firing Filter: 'OAuth2LoginAuthenticationFilter'
2020-02-19 16:10:33.930 DEBUG 19564 --- [qtp148813381-20] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login/oauth2/code/azure'; against '/login/oauth2/code/*'
2020-02-19 16:10:33.930 DEBUG 19564 --- [qtp148813381-20] .s.o.c.w.OAuth2LoginAuthenticationFilter : Request is to process authentication
2020-02-19 16:10:33.930 DEBUG 19564 --- [qtp148813381-20] o.s.s.authentication.ProviderManager     : Authentication attempt using org.springframework.security.oauth2.client.authentication.OAuth2LoginAuthenticationProvider
2020-02-19 16:10:33.931 DEBUG 19564 --- [qtp148813381-20] o.s.s.authentication.ProviderManager     : Authentication attempt using org.springframework.security.oauth2.client.oidc.authentication.OidcAuthorizationCodeAuthenticationProvider
2020-02-19 16:10:34.273 DEBUG 19564 --- [qtp148813381-20] .s.a.DefaultAuthenticationEventPublisher : No event was found for the exception org.springframework.security.oauth2.core.OAuth2AuthenticationException
2020-02-19 16:10:34.275 DEBUG 19564 --- [qtp148813381-20] .s.o.c.w.OAuth2LoginAuthenticationFilter : Authentication request failed: org.springframework.security.oauth2.core.OAuth2AuthenticationException: [invalid_token_response] An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: 401 Unauthorized: [no body]

org.springframework.security.oauth2.core.OAuth2AuthenticationException: [invalid_token_response] An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: 401 Unauthorized: [no body]
    at org.springframework.security.oauth2.client.oidc.authentication.OidcAuthorizationCodeAuthenticationProvider.authenticate(OidcAuthorizationCodeAuthenticationProvider.java:148) ~[spring-security-o

2020-02-19 16:10:34.277 DEBUG 19564 --- [qtp148813381-20] .s.o.c.w.OAuth2LoginAuthenticationFilter : Updated SecurityContextHolder to contain null Authentication
2020-02-19 16:10:34.277 DEBUG 19564 --- [qtp148813381-20] .s.o.c.w.OAuth2LoginAuthenticationFilter : Delegating to authentication failure handler org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler@2b0d857b
2020-02-19 16:10:34.277 DEBUG 19564 --- [qtp148813381-20] .a.SimpleUrlAuthenticationFailureHandler : Redirecting to /login?error
2020-02-19 16:10:34.277 DEBUG 19564 --- [qtp148813381-20] o.s.s.web.DefaultRedirectStrategy        : Redirecting to '/login?error'
2020-02-19 16:10:34.277 DEBUG 19564 --- [qtp148813381-20] o.s.s.w.header.writers.HstsHeaderWriter  : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@2dd6e039
2020-02-19 16:10:34.277 DEBUG 19564 --- [qtp148813381-20] w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2020-02-19 16:10:34.278 DEBUG 19564 --- [qtp148813381-20] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
[...]

Попытки исправить эту ошибку

Я испробовал все решения из этого открытого вопроса: https://github.com/microsoft/azure-spring-boot/issues/526, включая включение oauth2AllowImplicitFlow в azure манифест портала, безрезультатно.

Если я распечатаю код авторизации из браузера eclipse и создаю запрос токена в azure AD (с azure коллекцией почтальонов ) Я получил успешный ответ с токеном на предъявителя.

Так почему я получаю 401 Несанкционированный при отправке моего запроса токена?

Буду признателен за любые предложения о том, как решить эту проблему. Я отчаянно ищу решение, и мой следующий шаг - попытаться зарегистрировать запрос на использование весеннего токена или проверить его с помощью wireshark (придется расшифровывать соединение TLS, поскольку конечная точка для azure равна https)

Спасибо, если вы прочитали это далеко:)

1 Ответ

0 голосов
/ 24 февраля 2020

Согласно моему тесту мы можем использовать следующий код

Мой файл конфигурации

spring:
  security:
    oauth2:
      client:
        registration:
           azure:
             client-id: xxx
             client-secret: xxx
             client-name: Azure
             client-authentication-method: basic
             provider: azure-oauth-provider
             scope: openid, https://graph.microsoft.com/user.read, profile
             redirect-uri: http://localhost:8080/login/oauth2/code/azure
             authorization-grant-type: authorization_code

        provider:
            azure-oauth-provider:
              authorization-uri: https://login.microsoftonline.com/<tenant id>/oauth2/v2.0/authorize
              user-info-uri: https://graph.microsoft.com/oidc/userinfo 
              token-uri: https://login.microsoftonline.com/<tenant id>/oauth2/v2.0/token
              jwk-set-uri: https://login.microsoftonline.com/<tenant id>/v2.0/keys
              user-name-attribute: name

azure:
  activedirectory:
    tenant-id: xxx
    active-directory-groups: ***

WebSecurityConfig. java

@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private OAuth2UserService<OidcUserRequest, OidcUser> oidcUserService;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
            .anyRequest().authenticated()
            .and()
            .oauth2Login()
            .userInfoEndpoint()
            .oidcUserService(oidcUserService);
    }
}

enter image description here

enter image description here

...