1

I'm writing a spring-boot application which is an Oauth2 client, I'm using my Organization's Oauth server (custom written). I'm running into trouble while fetching the access token. Initially, the call for the authorization code works fine, the server redirects to my application with code=RANDOM_AUTHORIZATION_CODE. But the application doesn't try to fetch the access token from this authorization code. It treats redirect request as a new one and fetches the code again, and the original call ends up giving ERR_TOO_MANY_REDIRECTS.

I am not sure if I am supposed to do something more (like fetch token manually making a network call from my application). I was unable to get any documentation regarding this. Can someone guide me on what I'm doing wrong?

Here's the configure method that is in the config class which extends WebSecurityConfigurerAdapter

@Override
protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                    .antMatchers("login","/login/**","oauth2/**")
                        .permitAll()
                    .anyRequest()
                        .authenticated()
                        .and()
                .oauth2Login()
                    .authorizationEndpoint()
                        .baseUri("/oauth2/authorize")
                        .authorizationRequestResolver(customAuthResolver())
                        .and()
                    .redirectionEndpoint()
                        .baseUri("/oauth2/callback")
                        .and()
                    .tokenEndpoint()
                        .accessTokenResponseClient(accessTokenResponseClient())
                        .and()
                    .userInfoEndpoint()
                        .and();
    }

 @Bean
public OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> accessTokenResponseClient() {
        DefaultAuthorizationCodeTokenResponseClient accessTokenResponseClient = new DefaultAuthorizationCodeTokenResponseClient();
        return accessTokenResponseClient;
    }

Here's the application.yml which has oauth2 configs.

security:
    basic:
        enabled: false
    oauth2:
        client:
            clientId: pgm-backend
            clientSecret: 2XmrKjm2AJkWrSl2WwaqMBioHHQB6YOgSlaBWR0
            accessTokenUri: https://auth.server.com/oauth2/token
            userAuthorizationUri: https://auth.server.com/oauth2/auth
            redirectUri: http://localhost:9095/oauth2/callback
            scope:
              - openid
              - offline
            tokenName: oauth_token
        resource:
            userInfoUri: https://auth.server.com/userinfo
            preferTokenInfo: false

Please note that, I wanted to override the state parameter Spring Security automatically adds to the authorization request before making the request to match the validations of the auth server, hence I used customAuthResolver() which is an instance of class that implements OAuth2AuthorizationRequestResolver .

The Error is as follows:

  • Auth server call goes like this: https://auth.server.com/oauth2/auth?response_type=code&client_id=pgm-backend&scope=openid%20offline&state={STATE}&redirect_uri=http://localhost:9095/oauth2/callback/pgm-backend

  • Redirection I get: http://localhost:9095/oauth2/callback/pgm-backend?code={CODE}&scope=openid%20offline&state={STATE}

  • This call is again treated as a new one and the application fetches another auth code. This happens a few times and I end up with ERR_TOO_MANY_REDIRECTS.

Debug logs

2019-07-31 22:53:29.082 DEBUG 1094 --- [  XNIO-1 task-1] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request '/api/v1/currency/code/23' matched by universal pattern '/**'
2019-07-31 22:53:29.083 DEBUG 1094 --- [  XNIO-1 task-1] o.s.security.web.FilterChainProxy        : /api/v1/currency/code/23 at position 1 of 15 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2019-07-31 22:53:29.085 DEBUG 1094 --- [  XNIO-1 task-1] o.s.security.web.FilterChainProxy        : /api/v1/currency/code/23 at position 2 of 15 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2019-07-31 22:53:29.086 DEBUG 1094 --- [  XNIO-1 task-1] w.c.HttpSessionSecurityContextRepository : No HttpSession currently exists
2019-07-31 22:53:29.086 DEBUG 1094 --- [  XNIO-1 task-1] w.c.HttpSessionSecurityContextRepository : No SecurityContext was available from the HttpSession: null. A new one will be created.
2019-07-31 22:53:29.088 DEBUG 1094 --- [  XNIO-1 task-1] o.s.security.web.FilterChainProxy        : /api/v1/currency/code/23 at position 3 of 15 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2019-07-31 22:53:29.088 DEBUG 1094 --- [  XNIO-1 task-1] o.s.security.web.FilterChainProxy        : /api/v1/currency/code/23 at position 4 of 15 in additional filter chain; firing Filter: 'LogoutFilter'
2019-07-31 22:53:29.088 DEBUG 1094 --- [  XNIO-1 task-1] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/logout', GET]
2019-07-31 22:53:29.089 DEBUG 1094 --- [  XNIO-1 task-1] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/api/v1/currency/code/23'; against '/logout'
2019-07-31 22:53:29.089 DEBUG 1094 --- [  XNIO-1 task-1] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/logout', POST]
2019-07-31 22:53:29.089 DEBUG 1094 --- [  XNIO-1 task-1] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request 'GET /api/v1/currency/code/23' doesn't match 'POST /logout'
2019-07-31 22:53:29.089 DEBUG 1094 --- [  XNIO-1 task-1] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/logout', PUT]
2019-07-31 22:53:29.089 DEBUG 1094 --- [  XNIO-1 task-1] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request 'GET /api/v1/currency/code/23' doesn't match 'PUT /logout'
2019-07-31 22:53:29.089 DEBUG 1094 --- [  XNIO-1 task-1] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/logout', DELETE]
2019-07-31 22:53:29.089 DEBUG 1094 --- [  XNIO-1 task-1] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request 'GET /api/v1/currency/code/23' doesn't match 'DELETE /logout'
2019-07-31 22:53:29.089 DEBUG 1094 --- [  XNIO-1 task-1] o.s.s.web.util.matcher.OrRequestMatcher  : No matches found
2019-07-31 22:53:29.089 DEBUG 1094 --- [  XNIO-1 task-1] o.s.security.web.FilterChainProxy        : /api/v1/currency/code/23 at position 5 of 15 in additional filter chain; firing Filter: 'OAuth2AuthorizationRequestRedirectFilter'
2019-07-31 22:53:29.103 DEBUG 1094 --- [  XNIO-1 task-1] o.s.s.web.DefaultRedirectStrategy        : Redirecting to 'https://auth.dev.server.com/oauth2/auth?response_type=code&client_id=pgm-backend&scope=openid%20offline&state=A17nHr-X3SO0fovVsVKUs0XbfxwknQ0kYZnfAYubNEw%3D&redirect_uri=http://localhost:9095/oauth2/callback'
2019-07-31 22:53:29.103 DEBUG 1094 --- [  XNIO-1 task-1] 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@5508a98e
2019-07-31 22:53:29.104 DEBUG 1094 --- [  XNIO-1 task-1] w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2019-07-31 22:53:29.129 DEBUG 1094 --- [  XNIO-1 task-1] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
=======================================================
2019-07-31 22:53:29.603 DEBUG 1094 --- [  XNIO-1 task-2] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request '/oauth2/callback' matched by universal pattern '/**'
2019-07-31 22:53:29.603 DEBUG 1094 --- [  XNIO-1 task-2] o.s.security.web.FilterChainProxy        : /oauth2/callback?code=jF6na6l9dkyvdFvw6gXZenvxAG02ww4YuV1DCfH6Dks.q79aNezWFuP-PK_JXgbEz7KhUEmv6VRe12obVB3j8ho&scope=openid%20offline&state=A17nHr-X3SO0fovVsVKUs0XbfxwknQ0kYZnfAYubNEw%3D at position 1 of 15 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2019-07-31 22:53:29.603 DEBUG 1094 --- [  XNIO-1 task-2] o.s.security.web.FilterChainProxy        : /oauth2/callback?code=jF6na6l9dkyvdFvw6gXZenvxAG02ww4YuV1DCfH6Dks.q79aNezWFuP-PK_JXgbEz7KhUEmv6VRe12obVB3j8ho&scope=openid%20offline&state=A17nHr-X3SO0fovVsVKUs0XbfxwknQ0kYZnfAYubNEw%3D at position 2 of 15 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2019-07-31 22:53:29.604 DEBUG 1094 --- [  XNIO-1 task-2] w.c.HttpSessionSecurityContextRepository : HttpSession returned null object for SPRING_SECURITY_CONTEXT
2019-07-31 22:53:29.604 DEBUG 1094 --- [  XNIO-1 task-2] w.c.HttpSessionSecurityContextRepository : No SecurityContext was available from the HttpSession: io.undertow.servlet.spec.HttpSessionImpl@1dede21d. A new one will be created.
2019-07-31 22:53:29.604 DEBUG 1094 --- [  XNIO-1 task-2] o.s.security.web.FilterChainProxy        : /oauth2/callback?code=jF6na6l9dkyvdFvw6gXZenvxAG02ww4YuV1DCfH6Dks.q79aNezWFuP-PK_JXgbEz7KhUEmv6VRe12obVB3j8ho&scope=openid%20offline&state=A17nHr-X3SO0fovVsVKUs0XbfxwknQ0kYZnfAYubNEw%3D at position 3 of 15 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2019-07-31 22:53:29.604 DEBUG 1094 --- [  XNIO-1 task-2] o.s.security.web.FilterChainProxy        : /oauth2/callback?code=jF6na6l9dkyvdFvw6gXZenvxAG02ww4YuV1DCfH6Dks.q79aNezWFuP-PK_JXgbEz7KhUEmv6VRe12obVB3j8ho&scope=openid%20offline&state=A17nHr-X3SO0fovVsVKUs0XbfxwknQ0kYZnfAYubNEw%3D at position 4 of 15 in additional filter chain; firing Filter: 'LogoutFilter'
2019-07-31 22:53:29.604 DEBUG 1094 --- [  XNIO-1 task-2] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/logout', GET]
2019-07-31 22:53:29.604 DEBUG 1094 --- [  XNIO-1 task-2] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/oauth2/callback'; against '/logout'
2019-07-31 22:53:29.604 DEBUG 1094 --- [  XNIO-1 task-2] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/logout', POST]
2019-07-31 22:53:29.604 DEBUG 1094 --- [  XNIO-1 task-2] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request 'GET /oauth2/callback' doesn't match 'POST /logout'
2019-07-31 22:53:29.604 DEBUG 1094 --- [  XNIO-1 task-2] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/logout', PUT]
2019-07-31 22:53:29.604 DEBUG 1094 --- [  XNIO-1 task-2] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request 'GET /oauth2/callback' doesn't match 'PUT /logout'
2019-07-31 22:53:29.604 DEBUG 1094 --- [  XNIO-1 task-2] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/logout', DELETE]
2019-07-31 22:53:29.604 DEBUG 1094 --- [  XNIO-1 task-2] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request 'GET /oauth2/callback' doesn't match 'DELETE /logout'
2019-07-31 22:53:29.604 DEBUG 1094 --- [  XNIO-1 task-2] o.s.s.web.util.matcher.OrRequestMatcher  : No matches found
2019-07-31 22:53:29.604 DEBUG 1094 --- [  XNIO-1 task-2] o.s.security.web.FilterChainProxy        : /oauth2/callback?code=jF6na6l9dkyvdFvw6gXZenvxAG02ww4YuV1DCfH6Dks.q79aNezWFuP-PK_JXgbEz7KhUEmv6VRe12obVB3j8ho&scope=openid%20offline&state=A17nHr-X3SO0fovVsVKUs0XbfxwknQ0kYZnfAYubNEw%3D at position 5 of 15 in additional filter chain; firing Filter: 'OAuth2AuthorizationRequestRedirectFilter'
2019-07-31 22:53:29.605 DEBUG 1094 --- [  XNIO-1 task-2] o.s.s.web.DefaultRedirectStrategy        : Redirecting to 'https://auth.dev.server.com/oauth2/auth?response_type=code&client_id=pgm-backend&scope=openid%20offline&state=9vVqWfKQCu24UWrG9hItXiFGqExrfSQ6OEYKyJUu-nI%3D&redirect_uri=http://localhost:9095/oauth2/callback'
2019-07-31 22:53:29.606 DEBUG 1094 --- [  XNIO-1 task-2] 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@5508a98e
2019-07-31 22:53:29.606 DEBUG 1094 --- [  XNIO-1 task-2] w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2019-07-31 22:53:29.607 DEBUG 1094 --- [  XNIO-1 task-2] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
=======================================================
2019-07-31 22:53:30.407 DEBUG 1094 --- [  XNIO-1 task-3] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request '/oauth2/callback' matched by universal pattern '/**'
2019-07-31 22:53:32.106 DEBUG 1094 --- [  XNIO-1 task-6] o.s.security.web.FilterChainProxy        : /oauth2/callback?code=jIhYeU5grp9temJiB8WT94ctAyfQrRXDAkHZBO8vMRc.6DSC0Yo7a37uRKj69TYb4WzBd4MivaqmrksZPLvwaFM&scope=openid%20offline&state=4mz3iODP4Z6I9NoVM8XUjGxToUdumyQj5Skksd0oD8M%3D at position 1 of 15 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2019-07-31 22:53:32.106 DEBUG 1094 --- [  XNIO-1 task-6] o.s.security.web.FilterChainProxy        : /oauth2/callback?code=jIhYeU5grp9temJiB8WT94ctAyfQrRXDAkHZBO8vMRc.6DSC0Yo7a37uRKj69TYb4WzBd4MivaqmrksZPLvwaFM&scope=openid%20offline&state=4mz3iODP4Z6I9NoVM8XUjGxToUdumyQj5Skksd0oD8M%3D at position 2 of 15 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2019-07-31 22:53:32.108 DEBUG 1094 --- [  XNIO-1 task-6] w.c.HttpSessionSecurityContextRepository : HttpSession returned null object for SPRING_SECURITY_CONTEXT
2019-07-31 22:53:32.108 DEBUG 1094 --- [  XNIO-1 task-6] w.c.HttpSessionSecurityContextRepository : No SecurityContext was available from the HttpSession: io.undertow.servlet.spec.HttpSessionImpl@1dede21d. A new one will be created.
2019-07-31 22:53:32.108 DEBUG 1094 --- [  XNIO-1 task-6] o.s.security.web.FilterChainProxy        : /oauth2/callback?code=jIhYeU5grp9temJiB8WT94ctAyfQrRXDAkHZBO8vMRc.6DSC0Yo7a37uRKj69TYb4WzBd4MivaqmrksZPLvwaFM&scope=openid%20offline&state=4mz3iODP4Z6I9NoVM8XUjGxToUdumyQj5Skksd0oD8M%3D at position 3 of 15 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2019-07-31 22:53:32.108 DEBUG 1094 --- [  XNIO-1 task-6] o.s.security.web.FilterChainProxy        : /oauth2/callback?code=jIhYeU5grp9temJiB8WT94ctAyfQrRXDAkHZBO8vMRc.6DSC0Yo7a37uRKj69TYb4WzBd4MivaqmrksZPLvwaFM&scope=openid%20offline&state=4mz3iODP4Z6I9NoVM8XUjGxToUdumyQj5Skksd0oD8M%3D at position 4 of 15 in additional filter chain; firing Filter: 'LogoutFilter'
2019-07-31 22:53:32.108 DEBUG 1094 --- [  XNIO-1 task-6] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/logout', GET]

.... so on, in a loop

Please also note that the auth server is being used by other python and javascript based applications successfully, and any error is only from my application.

1 Answers1

0

My issue was in the custom authorization request resolver. I was not returning null as the OAuth2AuthorizationRequest in the resolve method (which overrides resolve method of OAuth2AuthorizationRequestResolver) in the case where registrationId was null. So OAuth2AuthorizationRequestRedirectFilter was being applied to all URLs instead of only the auth callback one.

  • I am having a similar problem but I am not using custom authorization request resolver. Can you as well post your resolver code and the change you did there to resolve it? – Siva Senthil Nov 15 '19 at 12:29
  • I wrote `private OAuth2AuthorizationRequest resolve()` method, where I was not returning null if registrationId was null earlier, which was causing the issue. Later on, I've added that check as the first line and it solved the issue. – Riyaz Mohammed Nov 19 '19 at 07:32
  • @RiyazMohammed I didn't quite understand what was the issue and how you solved it. I have exactly the same problem now. After authorization the server sens a redirect with the `code` parameter, and same loop happens until I get an error. Could you post the your code? Or at least the part which fixes the problem? – Andrey E Nov 22 '19 at 16:49
  • @AndreyE My issue occured because of my custom authorization request resolver. If you have too have written a custom resolver, then the `resolve` method should return null when `registrationId` is null. If not, then it is not related to this forum. – Riyaz Mohammed Dec 11 '19 at 10:10