我有一个奇怪的要求,即只使用 cookie 来验证请求。有一个用 PHP 编写的主要服务,它的会话使用名为 PHPSESSID
的 cookie 处理。
┌─────────┐
│ │
┌─────────┤ Browser ├───────────────┐
│ │ │ │
│ └─────────┘ │
┌──────▼─────┐ ┌──────────▼──────────┐
│ │ │ │
│ PHP Server ◄──────────────────┤ Spring Boot Service │
│ │ │ │
└──────┬─────┘ └──────────┬──────────┘
│ │
│ │
│ ┌───────────┐ │
│ │ │ │
└─────────► Database ◄─────────────┘
│ │
└───────────┘
Web 应用程序使用的服务的一小部分由 Spring Boot 服务提供。现在我想使用 PHP 会话 id 对进入 Spring 服务的请求进行身份验证。同时我想允许 CORS。但是当启用自定义安全过滤器时,由于 CORS 错误,从 Web 应用程序发送的请求失败。
@Configuration
@EnableWebSecurity(debug = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// When following custom authentication filter is added to the filter chain,
// requests from browser will fail due CORS error
// without it, everything just works fine
http.addFilterBefore(new MainAppAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
http.csrf().disable() //
.authorizeRequests() //
.anyRequest().permitAll() //
.and().httpBasic();
}
@Bean
public FilterRegistrationBean corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.addAllowedOrigin("http://localhost");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
bean.setOrder(0);
return bean;
}
}
public class MainAppAuthenticationFilter extends GenericFilterBean {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
var httpRequest = (HttpServletRequest) request;
var cookies = httpRequest.getCookies();
// check the session with PHP service
var user = userIsValid(cookie);
if(user != null) {
Authentication authentication = new UsernamePasswordAuthenticationToken(user.getName(), null,
AuthorityUtils.createAuthorityList(user.getRole()));
SecurityContextHolder.getContext().setAuthentication(authentication);
chain.doFilter(request, response);
} else {
var httpResponse = (HttpServletResponse) response;
httpResponse.sendError(401);
}
}
}
如何在使用自定义身份验证过滤器时启用 CORS?
答案 0 :(得分:0)
你可以试试这个:
http.csrf().disable().cors().and()
.authorizeRequests()
.anyRequest().permitAll()
.and().httpBasic();
答案 1 :(得分:0)
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
// Configure your Cors COnfig
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
然后将 http.cors() 添加到您的配置中。
答案 2 :(得分:0)
问题似乎是我如何添加允许的 CORS 方法和 allowCredentials。
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("http://localhost");
config.addAllowedHeader("*");
config.addAllowedMethod("OPTIONS");
config.addAllowedMethod("GET");
config.addAllowedMethod("POST");
config.addAllowedMethod("PUT");
config.addAllowedMethod("DELETE");
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
由于安全配置中没有 cors()
的某些原因,来自 Chrome 浏览器的 POST 请求将失败(但在 Firefox 上有效)。
http.csrf().disable().cors().and().authorizeRequests().anyRequest().permitAll();