无法在单个 Oauth 安全 Spring 控制器中拥有安全和非安全端点
Unable to have a secure and non secure endpoint in a single Oauth secured Spring controller
我正在使用 Spring 启动将 REST api 组合在一起,它将通过 OAuth2 进行保护。我构建了一个安全应用程序,它可以很好地管理 jwt 令牌。
我正在组装一个单独的应用程序,它将处理一些一般的用户配置文件资源请求,例如忘记密码、注册和配置文件获取操作。这是用 EnableOAuth2Resource 注释的,它正确地将 OAuth2AuthenticationProcessingFilter 添加到过滤器链。
@SpringBootApplication
@EnableOAuth2Resource
public class ProfileApplication extends SpringBootServletInitializer {
public static void main(String[] args) throws IOException {
SpringApplication.run(ProfileApplication.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(ProfileApplication.class);
}
}
我面临的挑战是我无法找到一种方法来配置安全性,以便 POST 对 /profiles 端点的请求是不安全的,而对 GET 或 PUT 的请求则通过提供的派生 @AuthenticationPrincipal 传递不记名令牌。
我想在 API 中包含以下内容
POST /profile 创建一个新用户 - 不安全
GET /profile/{id} 通过 id 获取用户 - 需要管理员权限或用户已授权
POST /password/reset - 开始密码重置 - 不安全
我有以下 bean 来配置安全性
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Order(-10) //SecurityProperties.ACCESS_OVERRIDE_ORDER)
class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/", "/public/**").permitAll()
.antMatchers(HttpMethod.POST, "/profiles/**").permitAll()
.antMatchers(HttpMethod.GET, "/profiles/**").fullyAuthenticated()
.antMatchers("/password/**").permitAll()
.anyRequest().fullyAuthenticated()
.and()
.csrf().disable();
}
}
使用上面的 GET 端点调用失败并出现 403 错误,没有任何尝试从令牌中查找当前用户,但是 post 将通过。查看日志,我不再在过滤器链中看到 OAuth2AuthenticationProcessingFilter。我尝试添加一些额外的过滤器似乎导致它不再被注册。
这个控制器方法看起来像:
@RequestMapping(method = {RequestMethod.GET}, value="/profiles/{login:.+}")
@ResponseBody
public ResponseEntity<Profile> get(@AuthenticationPrincipal Principal currentUser, @PathVariable String login) {
如果我将订单设置为 SecurityProperties.ACCESS_OVERRIDE_ORDER,那么 GET 请求会起作用,并且我会根据 jwt 承载令牌中的配置文件看到针对我的 oauth 服务的查找,但是 POST 请求要么配置文件或密码控制器失败并显示 401。因此,代码似乎永远不会到达此过滤器,而是被 OAuth2AuthenticationProcessingFilter 拦截,并且请求立即失败。
有没有办法在使用@EnableOAuth2Resource 时部分保护 Spring 启动应用程序?我是否必须设置不同的配置 bean 来提供必要的覆盖,如果需要,基于什么接口?
我认为您应该将 oauth2
资源从 SecurityConfig
中的请求匹配器中移走,并允许它们由资源服务器过滤器处理 - class 正在扩展 ResourceServerConfigurerAdapter
.
我的回答受到 Dave Syer 给出的回答的启发 . You can find a good security config here。
或者尝试给 bean 一个更高的顺序。
@maleenc 上面的建议是正确的。我缺少以下 ResourceServerConfigurerAdapter。添加我的 OAuth2ServerConfiguration class 并删除其他安全过滤器解决了我的问题
@Configuration
public class OAuth2ServerConfiguration {
@Configuration
@EnableResourceServer
protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/", "/public/**").permitAll()
.antMatchers("/password/**").permitAll()
.antMatchers(HttpMethod.POST, "/profiles").permitAll()
.and()
.csrf().disable();
}
}
}
我正在使用 Spring 启动将 REST api 组合在一起,它将通过 OAuth2 进行保护。我构建了一个安全应用程序,它可以很好地管理 jwt 令牌。
我正在组装一个单独的应用程序,它将处理一些一般的用户配置文件资源请求,例如忘记密码、注册和配置文件获取操作。这是用 EnableOAuth2Resource 注释的,它正确地将 OAuth2AuthenticationProcessingFilter 添加到过滤器链。
@SpringBootApplication
@EnableOAuth2Resource
public class ProfileApplication extends SpringBootServletInitializer {
public static void main(String[] args) throws IOException {
SpringApplication.run(ProfileApplication.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(ProfileApplication.class);
}
}
我面临的挑战是我无法找到一种方法来配置安全性,以便 POST 对 /profiles 端点的请求是不安全的,而对 GET 或 PUT 的请求则通过提供的派生 @AuthenticationPrincipal 传递不记名令牌。
我想在 API 中包含以下内容 POST /profile 创建一个新用户 - 不安全 GET /profile/{id} 通过 id 获取用户 - 需要管理员权限或用户已授权 POST /password/reset - 开始密码重置 - 不安全
我有以下 bean 来配置安全性
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Order(-10) //SecurityProperties.ACCESS_OVERRIDE_ORDER)
class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/", "/public/**").permitAll()
.antMatchers(HttpMethod.POST, "/profiles/**").permitAll()
.antMatchers(HttpMethod.GET, "/profiles/**").fullyAuthenticated()
.antMatchers("/password/**").permitAll()
.anyRequest().fullyAuthenticated()
.and()
.csrf().disable();
}
}
使用上面的 GET 端点调用失败并出现 403 错误,没有任何尝试从令牌中查找当前用户,但是 post 将通过。查看日志,我不再在过滤器链中看到 OAuth2AuthenticationProcessingFilter。我尝试添加一些额外的过滤器似乎导致它不再被注册。
这个控制器方法看起来像:
@RequestMapping(method = {RequestMethod.GET}, value="/profiles/{login:.+}")
@ResponseBody
public ResponseEntity<Profile> get(@AuthenticationPrincipal Principal currentUser, @PathVariable String login) {
如果我将订单设置为 SecurityProperties.ACCESS_OVERRIDE_ORDER,那么 GET 请求会起作用,并且我会根据 jwt 承载令牌中的配置文件看到针对我的 oauth 服务的查找,但是 POST 请求要么配置文件或密码控制器失败并显示 401。因此,代码似乎永远不会到达此过滤器,而是被 OAuth2AuthenticationProcessingFilter 拦截,并且请求立即失败。
有没有办法在使用@EnableOAuth2Resource 时部分保护 Spring 启动应用程序?我是否必须设置不同的配置 bean 来提供必要的覆盖,如果需要,基于什么接口?
我认为您应该将 oauth2
资源从 SecurityConfig
中的请求匹配器中移走,并允许它们由资源服务器过滤器处理 - class 正在扩展 ResourceServerConfigurerAdapter
.
我的回答受到 Dave Syer 给出的回答的启发
或者尝试给 bean 一个更高的顺序。
@maleenc 上面的建议是正确的。我缺少以下 ResourceServerConfigurerAdapter。添加我的 OAuth2ServerConfiguration class 并删除其他安全过滤器解决了我的问题
@Configuration
public class OAuth2ServerConfiguration {
@Configuration
@EnableResourceServer
protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/", "/public/**").permitAll()
.antMatchers("/password/**").permitAll()
.antMatchers(HttpMethod.POST, "/profiles").permitAll()
.and()
.csrf().disable();
}
}
}