Spring 使用 Jersey 和 Spring Security OAuth2 启动
Spring Boot with Jersey and Spring Security OAuth2
按照 Spring 引导中的示例: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-jersey
和 spring-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();
}
}
提前致谢!
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
开头的请求。
按照 Spring 引导中的示例: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-jersey
和 spring-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();
}
}
提前致谢!
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
开头的请求。