使用Jersey和Spring Security OAuth2进行Spring Boot

时间:2017-05-04 08:14:12

标签: spring-mvc spring-boot spring-security jersey-2.0 spring-security-oauth2

以下来自Spring Boot的示例:example code from GitHub一切似乎都正常。

但是当我在项目中集成Spring Boot Security OAuth2时,我的OAuth2端点就停止工作了。日志中有警告:

2017-05-04 08:56:24.109 WARN 2827 --- [nio-8080-exec-1] o.glassfish.jersey.servlet.WebComponent : A servlet request to the URI http://127.0.0.1:8080/oauth/token contains form parameters in the request body but the request body has been consumed by the servlet or a servlet filter accessing the request parameters. Only resource methods using @FormParam will work as expected. Resource methods consuming the request body by other means will not work as expected.

这让我觉得即使我没有注册端点,Jersey正在捕获它并处理正文,使得Spring MVC无法接受请求......

我的泽西配置是:

@Component
public class JerseyConfig extends ResourceConfig {

    public JerseyConfig() {
        register(InfoController.class);
    }

}

我的信息控制器非常简单:

@Component
@Path("/me")
@Produces("application/json")
public class InfoController {
  @GET
  public String meAction() {
    return "Hi";
  }
}

最后,我试图制作的电话会在日志中引发警告:

curl -X POST -u CLIENT_APPLICATION:123456789 http://127.0.0.1:8080/oauth/token -H "Accept: application/json" -d "password=aaa&username=aa&grant_type=password&client_id=CLIENT_APPLICATION"

在这个意义上,两个项目(spring-boot-starter-jerseyspring-security-oauth2之间是否存在已知的不兼容性?

删除Jersey配置使一切正常,但我需要在我的控制器上使用它。

我对OAuth2的配置是:

@Configuration
public class OAuth2ServerConfiguration {
  @Configuration
  @EnableResourceServer
  protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
    @Override
    public void configure(ResourceServerSecurityConfigurer resources) {
      resources.resourceId("OAuth2 Server");
    }
    @Override
    public void configure(HttpSecurity http) throws Exception {
      // @formatter:off
      http
          .authorizeRequests()
          .antMatchers("/oauth/token").permitAll()
          .antMatchers("/*").authenticated();
      // @formatter:on
    }
  }
}

然后是安全配置本身:

@Configuration
@EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {

  private final ApiUserDetailsService userDetailsService;

  @Autowired
  public WebSecurityConfiguration(ApiUserDetailsService userDetailsService) {
    this.userDetailsService = userDetailsService;
  }

  @Override
  protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(userDetailsService);
  }

  @Bean
  @Override
  public AuthenticationManager authenticationManagerBean() throws Exception {
    return super.authenticationManagerBean();
  }
}

提前致谢!

1 个答案:

答案 0 :(得分:3)

似乎泽西岛正在尝试处理OAuth端点,它不应该是。原因是Jersey的默认映射是/*,这意味着它将处理对所有URL的请求。您可以通过以下几种方式进行更改:

  1. 使用不同的映射在@ApplicationPath子类的顶部添加ResourceConfig

    @Component
    @ApplicationPath("/api")
    public class JerseyConfig extends ResourceConfig {}
    
  2. 您可以在application.properties文件中添加映射

    spring.jersey.application-path=/api
    
  3. 这将使/api前缀到您的所有Jersey端点,并且还使Jersey不能处理所有请求,只有那些以/api开头的请求。