'POST' 不支持带有 'password' grant_type 的“/oauth/token”端点

'POST' not supported for '/oauth/token' endpoint with 'password' grant_type

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

o.s.web.servlet.PageNotFound : Request method 'POST' not supported

注意:记录器是 pageNotFoundLoggerDispatcherServlet.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'

    }
}

主要 class:

@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 man 测试时 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"
}

怎么了?

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

希望对您有所帮助。

当我试图定义一个休息控制器时,我迷路了 @RequestMapping

  • 解决方案 1:将缺少的注释 @ReqeustMapping 添加到 OAuth2App 以完成其余控制器。
  • 解决方案 2:提取其余控制器内容以分隔 class。