带有 Jersey 和 Spring Security OAuth2 的 Spring Boot

Posted

技术标签:

【中文标题】带有 Jersey 和 Spring Security OAuth2 的 Spring Boot【英文标题】:Spring Boot with Jersey and Spring Security OAuth2 【发布时间】:2017-10-02 07:23:30 【问题描述】:

按照 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();
  

提前致谢!

【问题讨论】:

该警告并非特定于使用 oauth。当您使用 appliction/x-www-form-urlencoded 时,Jersey(我认为主要是 Tomcat)会发生这种情况。它只是告诉你,如果你想在 Jersey 资源方法中使用表单参数,你应该使用@FormParam(而不是其他方式)。对我来说,如果您收到此警告,则表明 oauth 配置不正确,因为 oauth 端点甚至不应该通过 Jersey。它应该只是spring-security。 @peeskillet 谢谢。但我假设如果端点不通过 Jersey(如您在配置中看到的那样),那么为什么要打印 OAuth 端点的警告? 重点是它应该通过泽西岛。 Spring Security 是一个 servlet 过滤器,它超出了 Jersey 应用程序的范围。因此,如果 Jersey 正在接受对 oauth 端点的请求,那么就有问题了。由于某种原因,Spring Security 没有处理该请求。我不太确定这个原因可能是什么。 我还没有真正使用过 Spring Security 的 oauth。端点是否配置为 Spring MVC 控制器,端点是否仅使用 spring 安全过滤器处理?如果将它们作为 Spring MVC 控制器处理,一个问题是如果您使用 /*(默认值)作为 Jersey 路径配置。这将导致无法访问 MVC 控制器。 【参考方案1】:

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

    在您的 ResourceConfig 子类之上添加一个 @ApplicationPath 并使用不同的映射

    @Component
    @ApplicationPath("/api")
    public class JerseyConfig extends ResourceConfig 
    

    您可以在 application.properties 文件中添加映射

    spring.jersey.application-path=/api
    

这将在您的所有 Jersey 端点前添加 /api,并且还会导致 Jersey 不处理所有请求,仅处理以 /api 开头的请求。

【讨论】:

天哪,谢谢!我面临同样的问题,但在基本身份验证。对于春季新手来说,这很难找到。

以上是关于带有 Jersey 和 Spring Security OAuth2 的 Spring Boot的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot Jersey 和监控 URL

Spring 4 vs Jersey 用于 REST Web 服务

如何在 Spring MVC 中使用 Jackson 和 Jersey 2 Client 反序列化 Joda DateTime?

spring boot com.sun.jersey.spi.container.servlet.ServletContainer

带有 MVC 的 Spring 3 JSON

Jersey+Spring+Maven(转)