【问题标题】:'POST' not supported for '/oauth/token' endpoint with 'password' grant_type具有“密码”授权类型的“/oauth/token”端点不支持“POST”
【发布时间】:2019-02-01 18:33:03
【问题描述】:

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

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

注意:记录器是pageNotFoundLogger in 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 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"
}

怎么了?

【问题讨论】:

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


    【解决方案1】:

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

    希望对您有所帮助。

    【讨论】:

    • 谢谢,您的演示项目有效。我仍在努力找出问题所在。
    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-02-11
      • 1970-01-01
      • 1970-01-01
      • 2018-09-07
      • 2015-10-30
      • 1970-01-01
      • 2017-09-18
      • 1970-01-01
      相关资源
      最近更新 更多