Spring Security with oAuth2 /oAuth/Token request 4

2019-09-02 20:06发布

问题:

I am using oAuth2 token with Spring Security. If am using using same configuration with Spring boot 1.3.0 and it working fine for me. But when i am using same configuration with Spring Mvc applicaito. Then it will creating a issue

/oAuth/token ---> Post 405 Method not allow.

My oAuth configuration is as:

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JdbcTokenStore;

@Configuration
public class OAuth2ServerConfiguration {

    @Configuration
    @EnableResourceServer
    protected static class ResourceServerConfiguration extends
            ResourceServerConfigurerAdapter {

        @Autowired
        private HttpUnauthorizedEntryPoint authenticationEntryPoint;

        @Override
        public void configure(HttpSecurity http) throws Exception {
            http
                .exceptionHandling()
                .authenticationEntryPoint(authenticationEntryPoint)
            .and()
                .csrf()
                .disable()
                .headers()
                .frameOptions().disable()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and()
                .authorizeRequests()
                .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
                .antMatchers("/webhook/**").permitAll() 
                .antMatchers("/app/**").permitAll() 
                .antMatchers("/api/**").authenticated() 
                .antMatchers("/protected/**").authenticated();

        }
    }

    @Configuration
    @EnableAuthorizationServer
    protected static class AuthorizationServerConfiguration extends
            AuthorizationServerConfigurerAdapter {

        @Autowired
        private DataSource dataSource;

        @Bean
        public TokenStore tokenStore() {
            return new JdbcTokenStore(dataSource);
        }

        @Autowired
        @Qualifier("authenticationManagerBean")
        private AuthenticationManager authenticationManager;

        @Override
        public void configure(AuthorizationServerEndpointsConfigurer endpoints)
                throws Exception {

            endpoints.tokenStore(tokenStore()).authenticationManager(
                    authenticationManager);
        }

        @Override
        public void configure(AuthorizationServerSecurityConfigurer oauthServer)
                throws Exception {
            oauthServer.allowFormAuthenticationForClients();
        }

        @Override
        public void configure(ClientDetailsServiceConfigurer clients) throws Exception { 
            clients
                .inMemory()
                .withClient(Constants.htgappClientId)
                .scopes("read", "write")
                .authorities("ROLE_ADMIN", "ROLE_USER") 
                .authorizedGrantTypes("password", "refresh_token", "authorization_code", "implicit")
                .secret(Constants.htgappClientSecret) 
                .accessTokenValiditySeconds(Constants.tokenValidityInSeconds);
        }
    }
}

Can any one help where I am wrong.

回答1:

You can specify the allowed methods as follows in the config:

@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { 
    endpoints.tokenStore(tokenStore()).authenticationManager(authenticationManager);
    endpoints.allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST)
}


回答2:

Default allowed is only POST for /oauth/token endpoint. So to allow the GET method we have to configure the REST endpoint. With just an XML config it's not possible to configure the allowed token endpoint methods. So creating an extra configuration class that will run a @PostConstruct method after the XML has run, to finish the job.

    @Configuration
    public class OauthTokenEndPointMethodConfig {

    @Autowired
    private TokenEndpoint tokenEndpoint;

    @PostConstruct
    public void reconfigure() {
        Set<HttpMethod> allowedMethods = new HashSet<>(Arrays.asList(HttpMethod.GET, HttpMethod.POST));
        tokenEndpoint.setAllowedRequestMethods(allowedMethods);
    }
  }