为什么 spring-security-oauth2 在令牌端点抛出未经授权的错误?如何开启对端点的访问?

Why is spring-security-oauth2 throwing unauthorized error at the token endpoint? How to open the access to the endpoint?

我正在尝试使用 spring 安全 oauth2 框架创建示例授权服务器。与任何其他 spring 相关示例相比,这些教程令人困惑。

更新: 如果您正在寻找可行的解决方案,请转到我的答案。忽略下面的代码。

当我调用令牌发布端点时,抛出以下错误

{
    "error": "unauthorized",
    "error_description": "Full authentication is required to access this resource"
}

这是我的设置(使用 Groovy)。我正在使用 spring-security-oauth2:2.3.4.RELEASE、spring-cloud-security:2.0.1.RELEASE 和 boot:2.1.1.RELEASE.

@Configuration
@CompileStatic
class OAuth2ClientSpringConfig extends AuthorizationServerConfigurerAdapter {

    @Autowired
    AuthenticationManager authenticationManager

    @Autowired
    UserDetailsService userDetailsService

    // register clients
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory().withClient('clientone')
                .secret('secret')
                .authorizedGrantTypes('password')
                .scopes('one', 'two')
    }

    //use default auth manager and user details service
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.authenticationManager(authenticationManager)
                .userDetailsService(userDetailsService)
    }

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        security.allowFormAuthenticationForClients()
        security.tokenKeyAccess("permitAll()")
                .checkTokenAccess("isAuthenticated()")
                .allowFormAuthenticationForClients()  //<--- update
    }
}

静态用户凭证

@Configuration
@CompileStatic
class UserCredentialsSpringConfig extends WebSecurityConfigurerAdapter {

    @Bean
    AuthenticationManager authenticationManagerBean() {
        super.authenticationManagerBean()
    }

    @Bean
    UserDetailsService userDetailsServiceBean() {
        super.userDetailsServiceBean()
    }

    protected void configure(AuthenticationManagerBuilder auth) {
        auth.inMemoryAuthentication()
                .withUser('user1').password('pwd1').roles('USER')
                .and()
                .withUser('admin').password('pwd1').roles('ADMIN')
    }

    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/oauth/token").permitAll()
                .anyRequest().authenticated()
    }
}

邮递员设置



当我点击http://localhost:8080/auth/oauth/token

时,

运行进入以下错误

我查看了不同的教程,但没有弄明白。任何输入都会有所帮助。

根据规范,the token issue endpoint 必须受到保护。

您必须提供 client_idclient_secret 作为参数(表格)或作为 http-basic 授权 header

直接取自规范

 POST /token HTTP/1.1
 Host: server.example.com
 Content-Type: application/x-www-form-urlencoded

 grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA
 &client_id=s6BhdRkqt3&client_secret=7Fjfp0ZBr1KtDRbnfVdmIw

请查看

https://www.rfc-editor.org/rfc/rfc6749#section-2.3.1

我们为什么不暂时将客户端从您的等式中移除,而只关注您的令牌端点

curl 是你的朋友,这里是一个 FORM 示例(针对 Cloud Foundry UAA 本地验证工作示例,其中客户端密码是一个空字符串)

curl -v \
    -H "Content-Type=application/x-www-form-urlencoded" \
    -H "Accept=application/json" \
    -d "grant_type=password" \
    -d "client_id=cf" \
    -d "response_type=token" \
    -d "username=marissa" \
    -d "password=koala" \
    -d "client_secret=" \
    http://localhost:8080/uaa/oauth/token

并使用 http-basic

curl -v \
    -H "Content-Type=application/x-www-form-urlencoded" \
    -H "Accept=application/json" \
    -d "grant_type=password" \
    -d "client_id=cf" \
    -d "response_type=token" \
    -d "username=marissa" \
    -d "password=koala" \
    -u "cf:" \
    http://localhost:8080/uaa/oauth/token

您能否 运行 这些命令与您的实际数据,让我们知道这些命令(也许更新您的问题)并让我们知道结果。你看,我们不知道你的 UI 应用程序实际在做什么,使用 curl 可以让我们从问题中消除它。

网上有几个教程,但其中一些没有提到他们正在使用 Boot 1.x。当我将这些指令与 Boot 2.x 组合在一起时,这就是我 运行 的目的。这些教程可能对 Boot 2.x 有效,但事情已经很混乱了,我无法找出一个工作模型。

这是启动 2.x 的有效解决方案。我从 https://github.com/spring-projects/spring-security-oauth2-boot/tree/master/samples/spring-boot-sample-secure-oauth2-provider 的代码示例重新开始。

导入 spring-security-oauth2-autoconfigure 依赖项。 将 @EnableAuthorizationServer 添加到您的主要 class。这就是最简单的工作模型所需的全部内容。无需添加 AuthorizationServerConfigurerAdapter 等,因为它是使用来自 application.yml 的数据自动配置的。看看上面的application.yml github link.

这是 Postman 配置

从 application.yml 复制示例客户端 ID 和密码并将它们作为 Auth headers.

提供

从启动日志中复制生成的密码并将其与其他属性一起放入Body表单数据中,如图所示。

就是这样。点击 http://localhost:8080/oauth/token,你应该会看到类似下面的内容