【问题标题】:Spring w/ @EnableOAuth2Sso client tries to access /oauth/token via GET rather than POSTSpring w/ @EnableOAuth2Sso 客户端尝试通过 GET 而不是 POST 访问 /oauth/token
【发布时间】:2018-02-26 12:54:22
【问题描述】:

我有一个 Spring Boot OAuth2 客户端和一个 Spring Boot OAuth 2 ResourceServer,它也是一个授权服务。我知道问题是什么。我知道 OAuth 2 令牌不允许通过 get,只有 Post。但是,我不知道如何解决它。这似乎是内置 @EnableOAuth2Sso 自动出现的。在下面的代码中,您可以看到该类是简单的骨骼。我没有在WebSecurityConfigurerAdapter 中看到提到处理这种情况的方法。

我不打算包含整个 POM,但我使用的是 Spring Boot 1.5.10.RELEASE,其中包括 spring-security-oauth2-2.0.14.RELEASE

我已经包含了我的类和属性文件,其中客户端 ID 和客户端秘密 XXX 已删除,首先是客户端类和道具:

客户端应用程序.properties:

server.port=7293
server.context-path=/ui
server.session.cookie.name=UISESSION

security.basic.enabled=false

security.oauth2.client.client-id=XXXXX
security.oauth2.client.client-secret=XXXXX
security.oauth2.client.access-token-uri=http://localhost:7291/auth/oauth/token
security.oauth2.client.user-authorization-uri=http://localhost:7291/auth/oauth/token
security.oauth2.resource.user-info-uri=http://localhost:7291/auth/user/me

spring.thymeleaf.cache=false

客户端安全配置:

@Configuration
@EnableOAuth2Sso
public class UISecurityConfig extends WebSecurityConfigurerAdapter {

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

Client Spring Boot 应用类:

@SpringBootApplication
public class OAuth2ClientApplication {

    public static void main(String[] args) {
        SpringApplication.run(OAuth2ClientApplication.class, args);
    }

    @Bean
    public RequestContextListener requestContextListener(){
        return new RequestContextListener();
    }   
}

资源/身份验证服务器应用程序类:

application.properties:

server.port=7291
server.context-path=/auth

security.oauth2.client.client-id=XXXXX
security.oauth2.client.client-secret=XXXXX

security.oauth2.authorization.checkTokenAccess=isAuthenticated()
security.oauth2.authorization.token-key-access=permitAll()

security.basic.enabled=false

认证服务器配置类:

@Configuration
@EnableAuthorizationServer
public class AuthServerConfig extends AuthorizationServerConfigurerAdapter {

    private static final Logger logger = LoggerFactory.getLogger(FilteringServiceAuthServerConfig.class);

    @Value("${security.oauth2.client.client-id}")
    private String clientId;

    @Value("${security.oauth2.client.client-secret}")
    private String clientSecret;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
          .withClient(clientId)
          .secret(clientSecret)
          .authorizedGrantTypes("authorization_code")
          .scopes("user_info")
          .autoApprove(true) ; 
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.authenticationManager(authenticationManager);
    }
}

这是我的授权服务器网络安全配置类:

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // @formatter:off
        http.requestMatchers()
          .antMatchers("/login", "/oauth/authorize", "/oauth/token")
          .and()
          .authorizeRequests()
          .anyRequest().authenticated()
          .and()
          .formLogin().permitAll();
        // @formatter:on
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.parentAuthenticationManager(authenticationManager)
            .inMemoryAuthentication()
            .withUser("XXXXX").password("XXXXX").roles("USER", "ADMIN");
    }
}

和授权/资源服务器组合 Spring Boot 应用程序类:

@SpringBootApplication
@EnableResourceServer
public class FilteringServiceApp extends SpringBootServletInitializer {

    private static Logger logger = LoggerFactory.getLogger(FilteringServiceApp.class);

    @Value("${matches.file.name}")
    private String fileName;

    @Autowired 
    private FilterMatchRepository matchRepo;

    @PostConstruct
    private void init() {
        new MatchInitializer(matchRepo, fileName).init();
    }

    /**
     * Start up the Filter Matching Application
     * 
     * @param args 
     */
    public static void main(String[] args) {
        SpringApplication.run(FilteringServiceApp.class, args);
    }

    @Bean
    public RequestContextListener requestContextListener(){
        return new RequestContextListener();
    } 
}

我以这种方式访问​​ URL 时遇到的错误(通过 client_id 和 secret_id 进行身份验证后是:

{ “错误”:“method_not_allowed”, "error_description": "不支持请求方法 'GET'" }

当我收到此错误消息时,我使用 Ngrok 查看发生了什么,您可以看到它显然正在通过违反规范的 GET 请求访问 /oauth/token。这是输出:

HTTP/1.1 302 
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Location: http://localhost:7291/auth/oauth/token?client_id=XXXXX&redirect_uri=http://57bfa798.ngrok.io/ui/login&response_type=code&state=BgLGhq
Content-Length: 0
Date: Mon, 26 Feb 2018 09:42:30 GMT

【问题讨论】:

    标签: java spring spring-boot oauth-2.0


    【解决方案1】:

    我更改了我的 AuthServerConfig 类

    public class AuthServerConfig extends AuthorizationServerConfigurerAdapter {
    
        //... other methods still the same. below fixed the error
        @Override
        public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
            endpoints.authenticationManager(authenticationManager)
                     .allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-01-06
      • 1970-01-01
      • 2020-03-28
      • 2013-09-24
      • 2014-08-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多