title: Spring Security OAuth2 redirect_uri callback results in 404
body: <p>I am trying to write a web-app that allows authentication by either JDBC or Google/Facebook; using Spring Security 5.0.x. I have valid Google Client Id and Secret. The OAuth2 web-flow is taking me correctly to Google for account selection and consent, but the callback to the redirect_uri is failing with a 404. I can't see what I'm doing wrong.</p>
  
  <pre><code>@Configuration
  @EnableScheduling
  @EnableWebSecurity
  public class WebSecurityConfig
      extends WebSecurityConfigurerAdapter
  {
      private static final Logger _logger = LogManager.getLogger (WebSecurityConfig.class);
  
      private static String
          SuccessUrl = "/api/auth/login-success",
          FailureUrl = "/api/auth/login-failure",
          LogoutUrl = "/api/auth/logout-done";
  
      private static String
          PGoogleId = "oauth2.google.id",
          PGoogleSecret = "oauth2.google.secret",
          PFacebookId = "oauth2.facebook.id",
          PFacebookSecret = "oauth2.google.secret";
  
      private final List&lt;ClientRegistration&gt; _regns;
  
      @Autowired
      private AuthSuccessHandler _success;
      @Autowired
      private AuthFailureHandler _failure;
      @Autowired
      private DataSource _source;
      @Autowired
      private MezoUserManager _userManager;
  
      /**
       * Sole Constructor
       */
      public WebSecurityConfig ()
      {
          _regns = new ArrayList&lt;&gt; ();
      }
  
      @Autowired
      public void setPropertiesFactory (
          PropertiesFactoryBean factory)
          throws IOException, AddressException
      {
          Properties p = factory.getObject ();
          extractIdSecret (CommonOAuth2Provider.GOOGLE.getBuilder ("google"), PGoogleId, PGoogleSecret, p);
          extractIdSecret (CommonOAuth2Provider.FACEBOOK.getBuilder ("facebook"), PFacebookId, PFacebookSecret, p);
      }
  
      private void extractIdSecret (
          ClientRegistration.Builder builder,
          String idKey,
          String secretKey,
          Properties properties)
      {
          String id = properties.getProperty (idKey);
          String secret = properties.getProperty (secretKey);
          if (StringUtils.isBlank (id) || StringUtils.isBlank (secret))
              return;
          _regns.add (builder.clientId (id).clientSecret (secret).build ());
      }
  
      @Override
      protected void configure (
          HttpSecurity http)
          throws Exception
      {
          _success.setUrl (SuccessUrl);
          _failure.setUrl (FailureUrl);
  
          JdbcTokenRepositoryImpl repo = new JdbcTokenRepositoryImpl ();
          repo.setDataSource (_source);
  
          http
              .authorizeRequests ()
                  .antMatchers ("/api/profile/**").authenticated ()
                  .antMatchers ("/api/users/**").hasAuthority (Authority.ROLE_ADMIN.name ())
              .antMatchers ("/api/**").permitAll ()
              .and ()
              .exceptionHandling ()
                  .authenticationEntryPoint (new Http403ForbiddenEntryPoint())
                  .and ()
              .formLogin ()
                  .loginProcessingUrl ("/login")
                  .loginPage ("/")
                  .successHandler (_success)
                  .failureHandler (_failure)
                  .and ()
              .logout ()
                  .logoutUrl ("/logout")
                  .logoutSuccessUrl (LogoutUrl)
                  .and ()
              .rememberMe ()
                  .tokenRepository (repo)
                  .tokenValiditySeconds (1209600)
                  .rememberMeParameter ("remember-me")
                  .and ()
              .csrf ().disable ();
  
          if (!_regns.isEmpty ())
          {
              http.oauth2Login ()
                  .clientRegistrationRepository (new InMemoryClientRegistrationRepository (_regns));
              _logger.debug ("OAuth2 entabled");
          }
      }
  
      @Override
      protected void configure (
          AuthenticationManagerBuilder builder)
          throws Exception
      {
          DaoAuthenticationProvider provider = new DaoAuthenticationProvider ();
          provider.setUserDetailsService (_userManager);
          provider.setPasswordEncoder (encoder ());
  
          builder.authenticationProvider (provider);
          builder.userDetailsService (_userManager);
      }
  
      @Bean
      public BCryptPasswordEncoder encoder ()
      {
          return new BCryptPasswordEncoder ();
      }
  }
  </code></pre>
  
  <p>The callback from Google is going to the right place:</p>
  
  <blockquote>
    <p><a href="http://localhost:8080/mezo/login/oauth2/code/google?state=" rel="nofollow noreferrer">http://localhost:8080/mezo/login/oauth2/code/google?state=</a>.....</p>
  </blockquote>
  
  <p>But my webapp complains with:</p>
  
  <blockquote>
    <p>HTTP Status 404 - /mezo/login</p>
  </blockquote>
  
  <p>Can anyone see what I've missed in my config? Why hasn't Spring Security automatically setting up the filters for the callback uri?</p>
  
  <p>Note that the login using JDBC currently works with this config.</p>