1
votes

I try to implement OAuth2 client using authorization-code grant flow by spring-boot. But it does not work.

"http://external_server/oauth/authorize" was called, but no GET arguments added.

Does anyone know what is wrong in below configuration?

Auth provider is implemented by doorkeeper and it's already working. so URL constants in WebSecurityConfiguration are correct.

@Configuration 
@EnableWebMvcSecurity 
@EnableOAuth2Client 
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {

  private static final String AUTH_ENDPOINT = "http://external_server";
  private static final String LOGIN_URL = AUTH_ENDPOINT + "/users/sign_in";
  private static final String LOGOUT_URL = AUTH_ENDPOINT + "/sign_out";

  private static final String AUTH_URL = AUTH_ENDPOINT + "/oauth/authorize";
  private static final String ACCESS_TOKEN_URL = AUTH_ENDPOINT + "/oauth/token";

  @Autowired OAuth2ClientContext oAuth2ClientContext;

  /**
   * for specific api
   */
  @Bean public RestTemplate restTemplate() {
    return new RestTemplate();
  }

  /**
   * for accessing protected resource
   */
  @Bean public OAuth2RestTemplate oAuth2RestTemplate() {
    return new OAuth2RestTemplate(resource(), oAuth2ClientContext);
  }

  @Bean protected OAuth2ProtectedResourceDetails resource() {

    AuthorizationCodeResourceDetails resource = new AuthorizationCodeResourceDetails();
    resource.setClientId("_xxx_");
    resource.setClientSecret("_yyy_");
    resource.setUserAuthorizationUri(AUTH_URL);
    resource.setAccessTokenUri(ACCESS_TOKEN_URL);

    return resource;
  }

  @Override public void configure(WebSecurity web) throws Exception {
    web.debug(true).ignoring().antMatchers("/webjars/**", "/css/**");
  }

  @Override protected void configure(HttpSecurity http) throws Exception {
    //@formatter:off
    http.csrf().disable().authorizeRequests()
        .antMatchers("/", "/callback")
        .permitAll()
        .anyRequest()
        .authenticated();

    http.formLogin()
        .loginPage(AUTH_URL)
        .loginProcessingUrl(LOGIN_URL);

    http.httpBasic()
        .disable();
    //@formatter:on
  }
}
1
OAuth2ProtectedResourceDetails is set in the OAuth2RestTemplate so that it will know what kind of grant flow you want to use. As it is, you are not taking advantage of it. - Luke Bajada
@bajada93 thanks for your comment! I fixed Configuration class to inject OAuth2RestTemplate, but still not work. - Yuki Yoshida
You need to add a OAuth2ClientAuthenticationProcessingFilter to the Spring Security Filter Chain and inject the OAuth2RestTemplate in it. That should do the trick. - Luke Bajada
@bajada93 thanks! I see gradually, but I assume these processes I'm trying are already implemented in spring-boot 1.3.0 - Yuki Yoshida

1 Answers

0
votes

By default only POST Method is enabled. You may need to include GET Method on AuthorizationConfig.

.allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST);

Will be like this:

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
    ....
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints){
        endpoints.authenticationManager(authenticationManager)
                .allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST);
    }
}

On source code of Spring Oauth we have:

private Set<HttpMethod> allowedTokenEndpointRequestMethods() {
        // HTTP POST should be the only allowed endpoint request method by default.
        if (allowedTokenEndpointRequestMethods.isEmpty()) {
            allowedTokenEndpointRequestMethods.add(HttpMethod.POST);
        }
        return allowedTokenEndpointRequestMethods;
    }