Spring Security + AngularJS:POST 请求
Posted
技术标签:
【中文标题】Spring Security + AngularJS:POST 请求【英文标题】:Spring Security + AngularJS: POST request 【发布时间】:2015-10-04 11:35:15 【问题描述】:我有一个 Web 应用程序,背面使用 Java Spring,正面使用 AngularJS。
Spring 安全配置(Java 配置):
@Override
protected void configure(HttpSecurity http) throws Exception
http
.authenticationProvider(authenticationProvider())
.exceptionHandling().authenticationEntryPoint(authenticationEntryPoint)
.and()
.formLogin().loginProcessingUrl("loginProcessingUrl")
.successHandler(authSuccessHandler)
.failureHandler(authFailureHandler)
.usernameParameter("username")
.passwordParameter("password")
.and()
.logout().permitAll().logoutSuccessHandler(logoutSuccessHandler)
.and()
.authorizeRequests().antMatchers("/demo/**","/postTest/**").permitAll()
.anyRequest().authenticated()
.and()
.httpBasic()
.and()
.csrf().csrfTokenRepository(csrfTokenRepository())
.and()
.addFilterAfter(new CsrfCustomFilter(), CsrfFilter.class);
CSRF 过滤器:
public class CsrfCustomFilter extends OncePerRequestFilter
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException
CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
if (csrf != null)
Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
String token = csrf.getToken();
if (cookie==null || token!=null && !token.equals(cookie.getValue()))
cookie = new Cookie("XSRF-TOKEN", token);
cookie.setPath("/");
response.addCookie(cookie);
filterChain.doFilter(request, response);
来自 AngularJS 的 POST 请求:
$http(method:'POST',data:"celine",url:"http://localhost:8080/postTest",cache:true)
.success(function(data)
console.log("success POST");
)
.error(function(data, status, headers, config, statusText)
console.log("status: " + status + " statusText: " + statusText);
);
-- 更新--
我可以使用从前到后的 GET 请求,但 POST 请求似乎不起作用。我在前端收到 403 Forbidden
错误(在我的日志中:“status: 403 statusText: undefined”)。
对于 POST 请求,我可以正确地向 Spring 发送 XSRF-TOKEN,但 Spring 返回 403 Forbidden
。所以我想问题出在我对 Spring Security 的配置上,而不是来自 Angular。
我的 POST 请求标头:
感谢您的宝贵时间。
【问题讨论】:
阅读 $http 文档以了解 Angular 如何处理标头中的 xsrf 标记 感谢您的帮助。来自文档:“为了利用这个 [CSRF 保护],您的服务器需要在第一个 HTTP GET 请求上设置一个名为 XSRF-TOKEN 的 javascript 可读会话 cookie 中的令牌。”但是我想我的问题是因为我的 Spring 端没有发送 XSRF-TOKEN。 你不能只添加一个cookie吗? 我用 Java 实现了 CsrfCustomFilter 类来发送一个名为 XSRF-TOKEN 的 cookie。但它在我的 POST 请求标头中不可见。但是,它在 GET 响应的标头中可见。 你在使用跨域请求吗?我的意思是,您的客户端应用程序与服务器应用程序在不同的端口上运行吗? 【参考方案1】:我在跨域请求中遇到了类似的问题,因为 AngularJS 不会在跨域请求中发送 XSRF 标头。 (在this page上搜索“不会为跨域请求设置标头”)。
写这个$http
拦截器
angular.module('appBoot')
.factory('XSRFInterceptor', function ($cookies, $log)
var XSRFInterceptor =
request: function(config)
var token = $cookies.get('XSRF-TOKEN');
if (token)
config.headers['X-XSRF-TOKEN'] = token;
$log.info("X-XSRF-TOKEN: " + token);
return config;
;
return XSRFInterceptor;
);
并像这样配置它
angular.module('appBoot', ['ngCookies', 'ngMessages', 'ui.bootstrap', 'vcRecaptcha'])
.config(['$httpProvider', function ($httpProvider)
$httpProvider.defaults.withCredentials = true;
$httpProvider.interceptors.push('XSRFInterceptor');
]);
解决了我的问题。
【讨论】:
谢谢,我会试试看,如果成功了会通知你。 我已经更新了我的问题。现在我可以从 Angular 发送 XSRF-TOKEN,但我仍然从服务器端收到“403 Forbidden”。 希望您的 csrfTokenRepository() 将标头的名称设置为X-XSRF-TOKEN
。我在github.com/naturalprogrammer/spring-lemon 有一个工作示例。看看 LemonSecurityConfig.java 等文件有没有帮助。
是的,csrfTokenRepository() 将标头的名称设置为 X-XSRF-TOKEN。谢谢,我会试试你的github例子..以上是关于Spring Security + AngularJS:POST 请求的主要内容,如果未能解决你的问题,请参考以下文章
Angular集成Spring Boot,Spring Security,JWT和CORS
Angular 2/Spring Security CSRF 实现问题
Angular 4.0 + Spring boot + Spring Security:TemplateInputException:解析模板“登录”时出错
如何使用 Spring Security + Angular 登录/验证