Reputation: 586
I have a web application with the back using Java Spring and the front using AngularJS.
Spring Security Configuration (Java config):
@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 filter:
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);
}
}
POST request from AngularJS:
$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);
});
-- UPDATED --
I can use a GET request from the front to the back, but the POST request doesn't seem to work. I get a 403 Forbidden
error on the front side (in my log: "status: 403 statusText: undefined").
For the POST request, I can correctly send a XSRF-TOKEN to Spring, but Spring returns 403 Forbidden
. So I guess that the problem is coming from my configuration of Spring Security and not from Angular.
My headers for the POST request:
Thank you for your time.
Upvotes: 1
Views: 2682
Reputation: 8965
I had a similar problem with cross domain requests, because AngularJS does not send the XSRF header in cross domain requests. (Search for "The header will not be set for cross-domain requests" on this page).
Writing this $http
interceptor
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;
});
and configuring it like this
angular.module('appBoot', ['ngCookies', 'ngMessages', 'ui.bootstrap', 'vcRecaptcha'])
.config(['$httpProvider', function ($httpProvider) {
$httpProvider.defaults.withCredentials = true;
$httpProvider.interceptors.push('XSRFInterceptor');
}]);
solved my problem.
Upvotes: 1