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

时间:2019-01-09 00:37:31

标签: spring-security spring-security-oauth2

我正在尝试使用spring security 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()
    }
}

邮递员设置

  • 在两个位置(授权标头和普通标头)添加了客户端凭据。

enter image description here


enter image description here

  • 使用正文形式参数发送用户凭据

enter image description here


在我碰到http://localhost:8080/auth/oauth/token

时遇到 以下错误

enter image description here

我研究了不同的教程,但没有弄清楚。任何输入都会有所帮助。

2 个答案:

答案 0 :(得分:1)

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

您必须提供client_idclient_secret作为参数(窗体)或http基本授权标头

直接从规格中获取

 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://tools.ietf.org/html/rfc6749#section-2.3.1

为什么我们不将客户端从您的方程式中删除一点,而只关注您的令牌端点

curl是您的朋友,这是一个FORM示例(针对Cloud Foundry UAA Local的经过验证的工作示例,其中客户密码为空字符串)

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可以让我们从问题中消除这一点。

答案 1 :(得分:0)

有几本在线教程,但其中有些没有提及他们正在使用Boot1.x。这就是我将这些指令与Boot 2.x结合使用时遇到的问题。这些教程在Boot 2.x上可能是有效的,但是事情已经很混乱了,以至于我无法确定工作模型。

这是Boot 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添加到您的主类。这就是最简单的工作模型所需要的。无需添加AuthorizationServerConfigurerAdapter等,因为它是使用application.yml中的数据自动配置的。在上面的github链接中查看application.yml。

这是邮递员配置

从application.yml复制示例客户端ID和密钥,并将其作为Auth标头提供。

enter image description here

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

enter image description here

就是这样。点击http://localhost:8080/oauth/token,您应该会在

下面看到类似的内容

enter image description here