CORS 允许自定义身份验证过滤器 |弹簧靴

时间:2021-03-24 18:25:47

标签: java spring spring-boot

我有一个奇怪的要求,即只使用 cookie 来验证请求。有一个用 PHP 编写的主要服务,它的会话使用名为 PHPSESSID 的 cookie 处理。

                   ┌─────────┐
                   │         │
         ┌─────────┤ Browser ├───────────────┐
         │         │         │               │
         │         └─────────┘               │
  ┌──────▼─────┐                  ┌──────────▼──────────┐
  │            │                  │                     │
  │ PHP Server ◄──────────────────┤ Spring Boot Service │
  │            │                  │                     │
  └──────┬─────┘                  └──────────┬──────────┘
         │                                   │
         │                                   │
         │         ┌───────────┐             │
         │         │           │             │
         └─────────► Database  ◄─────────────┘
                   │           │
                   └───────────┘

Web 应用程序使用的服务的一小部分由 Spring Boot 服务提供。现在我想使用 PHP 会话 id 对进入 Spring 服务的请求进行身份验证。同时我想允许 CORS。但是当启用自定义安全过滤器时,由于 CORS 错误,从 Web 应用程序发送的请求失败。

WebSecurityConfig.java

@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;
    }
}

MainAppAuthenticationFilter.java

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?

3 个答案:

答案 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();
相关问题