【发布时间】:2021-08-18 08:19:21
【问题描述】:
我的应用程序只需要支持一个 URL。像 http://.../service/api。要执行的操作取决于“ACTION”请求参数
为了解决这个问题,我创建了以下控制器
@RestController
public class Controller {
@PostMapping(path = "/api", params = "ACTION=INIT")
public String init() {
return "Inside Initialize";
}
@PostMapping(path = "/api", params = "ACTION=FETCH")
public String fetch() {
return "Inside Fetch";
}
@PostMapping(path="/view", param = "!ACTION")
public String view() {
return "Inside View";
}
当缺少 ACTION 参数时将调用 /view。对于前两个请求,我配置了 OAuth 身份验证,后者即 /view 将使用 formlogin。
我创建了一个过滤器,在其中检查 ACTION 参数,如果缺少,我将请求转发到 /view 处理程序。
@Component
public class RouteFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse, FilterChain filterChain)
throws ServletException, IOException {
if(!StringUtils.hasText(httpServletRequest.getParameter("ACTION"))){
httpServletRequest.getRequestDispatcher("/view").forward(httpServletRequest,httpServletResponse);
}else {
filterChain.doFilter(httpServletRequest,httpServletResponse);
}
}
下面是过滤器注册。我确保我的过滤器在 FilterChainProxy 之前被调用
@Autowired
private RouteFilter routeFilter;
@Bean
public FilterRegistrationBean<RouteFilter> filter() {
FilterRegistrationBean<RouteFilter> bean = new FilterRegistrationBean<>();
bean.setFilter(routeFilter);
bean.addUrlPatterns("/api");
bean.setOrder(-100);
return bean;
}
下面是安全配置
@Configuration
@Order(1)
public class Config extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/api")
.hasAuthority("SCOPE_API")
.anyRequest()
.authenticated()
.and()
.oauth2ResourceServer()
.opaqueToken();
}
}
@Configuration
@Order(2)
public class Config2 extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/view")
.permitAll()
.and()
.formLogin();
}
}
当我调用 /service/api 时,RouteFilter 将请求转发到 /view 处理程序,但与 /view 关联的 Spring Security 没有得到尊重。 Spring Security Filter 链是否不适用于转发的请求,或者我在这里遗漏了什么。我使用的是spring-boot 2.4.0版
【问题讨论】:
-
不是应该返回转发给客户端的响应吗……
-
不,过滤器链不会对转发的请求再次执行。如果要执行过滤器链,可以使用重定向而不是转发。
-
谢谢@dur。您分享的链接实际上帮助我了解了根本原因。
标签: java spring spring-boot spring-security