部署在WildFly 10的Spring Boot安全REST接口,Angular 5调用POST报403
解决WildFly部署后POST请求403 CSRF Token问题
看起来你遇到的问题核心在于WildFly和Tomcat对Cookie的默认处理逻辑不一样,导致Angular没法自动拿到CSRF Token并传递,进而触发了Spring Security的403拦截。我给你梳理几个关键解决步骤:
1. 调整Spring Security的CSRF Cookie配置
首先得确保Spring Security生成的CSRF Cookie允许前端JS读取,并且路径设置正确——这是Angular能拿到Token的前提:
@Configuration @EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .cors(Customizer.withDefaults()) // 必须启用CORS,不然跨域带Cookie会被拦截 .csrf(csrf -> csrf // 关键:把HttpOnly设为false,让Angular能通过JS读取Cookie .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) // 可选:强制Cookie路径为根路径,避免路径不匹配导致读不到 .csrfTokenRepository(customCsrfTokenRepository()) // 使用Spring Security推荐的Token处理方式,兼容更多场景 .csrfTokenRequestHandler(new XorCsrfTokenRequestAttributeHandler()) ) .authorizeHttpRequests(auth -> auth .anyRequest().authenticated() ) .formLogin(Customizer.withDefaults()); // 这里根据你的实际认证方式调整,比如JWT或OAuth2 return http.build(); } private CookieCsrfTokenRepository customCsrfTokenRepository() { CookieCsrfTokenRepository repository = CookieCsrfTokenRepository.withHttpOnlyFalse(); repository.setCookiePath("/"); return repository; } // 配置CORS,允许Angular携带凭证(Cookie) @Bean public CorsConfigurationSource corsConfigurationSource() { CorsConfiguration configuration = new CorsConfiguration(); configuration.setAllowCredentials(true); // 替换成你的Angular实际地址,比如http://localhost:4200,别用*,不然带Cookie会失效 configuration.addAllowedOriginPattern("http://localhost:4200"); configuration.addAllowedHeader("*"); configuration.addAllowedMethod("*"); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", configuration); return source; } }
2. 修改WildFly的Cookie默认配置
WildFly的Undertow服务器对Cookie的SameSite和HttpOnly属性默认设置和Tomcat不同,需要手动调整:
编辑WildFly的standalone.xml(或domain.xml),找到Undertow子系统的servlet-container节点,添加Cookie配置:
<subsystem xmlns="urn:jboss:domain:undertow:10.0" default-server="default-server" default-virtual-host="default-host" default-servlet-container="default" default-security-domain="other"> <server name="default-server"> <http-listener name="default" socket-binding="http" redirect-socket="https" enable-http2="true"/> <host name="default-host" alias="localhost"> <location name="/" handler="welcome-content"/> </host> </server> <servlet-container name="default"> <!-- 关键配置:让Cookie允许跨域传递,且JS可读取 --> <session-cookie http-only="false" same-site="Lax"/> <jsp-config/> <websockets/> </servlet-container> <!-- 其他配置... --> </subsystem>
3. 验证Angular端的自动XSRF处理
Angular的HttpClient默认会自动处理XSRF,但要确保你没破坏这个逻辑:
- 确认
AppModule里正确导入了HttpClientModule:
import { HttpClientModule } from '@angular/common/http'; @NgModule({ imports: [ HttpClientModule, // 其他模块 ], // ... }) export class AppModule { }
- 打开浏览器控制台,执行
document.cookie,检查是否存在XSRF-TOKEN这个Cookie。 - 用浏览器开发者工具的Network标签,查看POST请求的请求头,确认是否自动带上了
X-XSRF-TOKEN。
4. 排查跨域和HTTPS特殊情况
- 如果前后端是跨域部署,一定要保证CORS配置里
setAllowCredentials(true),并且allowedOrigin是具体的Angular地址(不能用*)。 - 如果用了HTTPS,Spring Security会自动给CSRF Cookie加上
Secure属性,这时候Angular也必须用HTTPS访问,否则浏览器不会发送这个Cookie。
5. 调试验证
重启WildFly和Angular应用后,再测试POST请求:
- 如果还是有问题,可以开启Spring Security的调试日志,查看Token生成和传递的细节:
logging.level.org.springframework.security=DEBUG
内容的提问来源于stack exchange,提问作者Savita Singh
相关产品推荐
相关产品推荐

