【问题标题】:Unauthorized error on Spring Boot Authorization Server /oauth/authorizeSpring Boot 授权服务器 /oauth/authorize 出现未经授权的错误
【发布时间】:2019-03-21 13:46:44
【问题描述】:

我正在尝试使用@EnableAuthorizationServer 和内存中的客户端为 Spring Boot 中的 OAuth2 授权服务器开发一个简单的 POC。

我的网络安全配置类如下所示:

package com.example.authservice;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.antMatcher("/**")
                .authorizeRequests().
                antMatchers("/", "/login**", "/oauth/authorize", "/oauth/authorize**")
                .permitAll().
                anyRequest()
                .authenticated();
    }
}

授权服务器配置如下:

package com.example.authservice;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory().
                withClient("auth-client").
                secret("secret-key").
                authorizedGrantTypes("authorization_code").
                scopes("openid");
    }

}

这是基于授权代码授予流程,当我尝试获取代码(将在下一次调用中用于获取访问令牌)时,我收到未经授权的错误。

curl -X GET \
  'http://localhost:8080/oauth/authorize?client_id=auth-client&client_secret=secret-key&grant_type=authorization_code&response_type=code'

错误:

{
    "timestamp": "2019-03-20T15:35:41.009+0000",
    "status": 403,
    "error": "Forbidden",
    "message": "Access Denied",
    "path": "/oauth/authorize"
}

我假设由于我的网络安全配置中允许/oauth/authorize,它应该返回一个可用于获取访问令牌的代码。有没有人知道可能出了什么问题。

【问题讨论】:

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


    【解决方案1】:
    /oauth/authorize 
    

    是默认的授权服务器端点,这意味着它具有高优先级安全级别。

    authorizeRequests().antMatchers("/oauth/authorize").permitAll()
    

    在 spring security 默认 api 上不起作用。如果您使用浏览器进行测试会更好

        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .inMemoryAuthentication().passwordEncoder(new PasswordEncoder() {
            @Override
            public String encode(CharSequence charSequence) {
                return charSequence.toString();
            }
    
            @Override
            public boolean matches(CharSequence charSequence, String s) {
                return s.equals(charSequence.toString());
            }
        })
            .withUser("gig")
            .password("123456")
            .roles("USER");
    
    }
    

    另外,最好在你的作用域之后添加一个 redirectUris。 我的测试网址

    http://localhost:8080/oauth/authorize?response_type=code&client_id=auth-client-&redirect_uri=http://www.baidu.com&scope=all
    

    【讨论】:

    • 除了我的回答之外,添加 redirect_uri 之后的观点是完全正确的,我错过了明确提及它。这个解决方案看起来像是完全捕捉到了它。非常感谢!
    【解决方案2】:

    当用户尝试通过调用/oauth/authorize 来生成授权码时,用户应该告诉服务他/她是谁,即进行身份验证。这就是授权端点知道用户是否被授权获取此令牌的方式。因此,我的服务中缺少的一个重要部分是身份验证。在 Spring Boot 中,身份验证由 AuthenticationManager 处理。

    补充缺失的部分,下面是WebSecurityConfigurerAdapter.java的修改版:

    package com.example.authservice;
    
    import org.springframework.context.annotation.Configuration;
    import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
    import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
    import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    
    @Configuration
    @EnableWebSecurity
    public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                    .csrf()
                    .disable()
                    .antMatcher("/**")
                    .authorizeRequests()
                    .antMatchers("/login")
                    .permitAll()
                    .anyRequest()
                    .authenticated()
                    .and().
                    httpBasic();
        }
    
        @Override
        public void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.inMemoryAuthentication().withUser("user").password("{noop}password").roles("ROLE");
        }
    }
    

    这为 Spring Boot 服务添加了基本 HTTP 身份验证。现在,当您尝试使用 HTTP 基本身份验证调用 /oauth/authorize 时,它将成功重定向到您传递的 redirect_uri

    【讨论】:

      猜你喜欢
      • 2018-07-04
      • 1970-01-01
      • 2014-03-08
      • 2022-11-08
      • 2019-04-05
      • 1970-01-01
      • 1970-01-01
      • 2022-01-21
      • 2020-10-22
      相关资源
      最近更新 更多