具有'password'grant_type的'/ oauth / token'端点不支持'POST'

时间:2018-08-27 08:45:44

标签: spring spring-boot spring-security spring-security-oauth2

我正在尝试了解密码授予类型,但是最简单的演示由于奇怪的原因而失败:

  

o.s.web.servlet.PageNotFound:请求方法'POST'不支持

注意:记录器在pageNotFoundLogger中是DispatcherServlet.java

我尝试更新依赖项以避免此问题,但失败了。

我使用的build.gradle:

buildscript {
    dependencies {
        classpath "io.spring.gradle:dependency-management-plugin:1.0.6.RELEASE"
    }
    repositories {
        mavenCentral()
    }
}

repositories {
    mavenCentral()
}

allprojects {
    apply plugin: "java"
    apply plugin: "io.spring.dependency-management"

    dependencyManagement {
        imports {
            mavenBom 'org.springframework.cloud:spring-cloud-netflix:2.0.1.RELEASE'
        }
    }

    sourceCompatibility = 1.8

    repositories {
        mavenCentral()
    }

    dependencies {
        testCompile group: 'junit', name: 'junit', version: '4.12'
        // https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web
        compile group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '2.0.4.RELEASE'
        compile 'org.springframework.cloud:spring-cloud-starter-oauth2:2.0.0.RELEASE'
        // https://mvnrepository.com/artifact/org.springframework.security.oauth/spring-security-oauth2
        compile group: 'org.springframework.security.oauth', name: 'spring-security-oauth2', version: '2.3.3.RELEASE'

    }
}

主要类别:

@RestController
@SpringBootApplication
public class OAuth2App {
    private static final Logger LOG = LoggerFactory.getLogger(OAuth2App.class);

    public static void main(String[] args) {
        SpringApplication.run(OAuth2App.class, args);
    }

    @GetMapping
    public String whoIam(Principal principal) {
        LOG.info("I'm {}", principal.getName());
        return principal.getName();
    }

    @Configuration
    public static class PasswordEncoderConfig {
        @SuppressWarnings("deprecation")
        @Bean
        public PasswordEncoder passwordEncoder() {
            // To avoid IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"
            return NoOpPasswordEncoder.getInstance();
        }
    }

    @Configuration
    public static class WebSecurityConfig extends WebSecurityConfigurerAdapter {
        private final PasswordEncoder passwordEncoder;

        @Autowired
        public WebSecurityConfig(PasswordEncoder passwordEncoder) {
            this.passwordEncoder = passwordEncoder;
        }

        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.eraseCredentials(true)
                    .inMemoryAuthentication()
                    .passwordEncoder(passwordEncoder)
                    .withUser("user")
                    .password(passwordEncoder.encode("password"))
                    .roles("USER");
        }

        @Bean
        @Override
        public AuthenticationManager authenticationManagerBean() throws Exception {
            return super.authenticationManagerBean();
        }
    }

    @Configuration
    @EnableAuthorizationServer
    public static class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

        private final AuthenticationManager authenticationManager;

        @Autowired
        public AuthorizationServerConfig(AuthenticationManager authenticationManager) {
            this.authenticationManager = authenticationManager;
        }

        @Override
        public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
            super.configure(clients);
            clients.inMemory()
                    .withClient("client")
                    .secret("secret") // not enhanced by password encoder yet
                    .authorizedGrantTypes("password")
                    .scopes("scope");
        }

        @Override
        public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
            super.configure(endpoints);
            endpoints.authenticationManager(authenticationManager);// To enable 'password' grant_type
        }
    }
}

当我使用邮递员测试POST http :: // client:secret @ localhost:8080 / oauth / token?grant_type = password&username = user&password = password时,它以

响应
{
    "timestamp": "2018-08-27T08:11:09.396+0000",
    "status": 405,
    "error": "Method Not Allowed",
    "message": "Request method 'POST' not supported",
    "path": "/oauth/token"
}

怎么了?

2 个答案:

答案 0 :(得分:1)

当我试图定义一个休息控制器时,我迷失了for ($i=1; $i <=3 ; $i++) { # code... echo "a ".$i; for ($j=1; $j <=3 ; $j++) { # code... echo "b ".$j; for ($k=1; $k <=3 ; $k++) { # code... echo "c ".$k; for ($m=1; $m <=3 ; $m++) { # code... echo "d ".$m; } } } }

  • 解决方案1:向@RequestMapping添加缺少的注释@ReqeustMapping,以完成其余控制器。
  • 解决方案2:将其余控制器内容提取到单独的类中。

答案 1 :(得分:0)

首先,您需要从Application类中删除@RestController批注。您需要为whoAmI方法创建一个单独的控制器。我已经实现了这个用例,您可以在我的GitHub上检查它 https://github.com/alex-petrov81/stackoverflow-answers/tree/master/post-not-supported-for-oauth-token-endpoint

希望有帮助。