在我的AngularJS authService中,我发送一个带有凭据和用户名的POST请求到一个单独的域上的服务器端点。 我有一个CORSFilter,因为我可以在SecurityConfiguration类中禁用CSRF保护时成功POST数据。
我做错了什么?如何使用POST请求发送CSRF令牌?
authService.login(凭证)
response.login = function (credentials) {
return $http({
method: "POST",
dataType: "json",
url: baseUrl + "/authenticate",
withCredentials: true,
data: { username: credentials.username },
headers: {
'Authorization' : "Basic " + btoa(credentials.username + ":" + credentials.password),
'Content-Type': 'application/json'
}
});
};
CsrfHeaderFilter
public class CsrfHeaderFilter 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);
}
}
SecurityConfiguration.java
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private CustomUserDetailsService customUserDetailsService;
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(customUserDetailsService).passwordEncoder(passwordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic()
.and()
.authorizeRequests()
.antMatchers("/**")
.permitAll().anyRequest().authenticated()
.and().csrf()
.csrfTokenRepository(csrfTokenRepository())
.and()
.addFilterAfter(new CsrfHeaderFilter(), CsrfFilter.class);
// .addFilterAfter(new CsrfHeaderFilter(), SessionManagementFilter.class);
}
private CsrfTokenRepository csrfTokenRepository() {
HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
repository.setHeaderName("X-XSRF-TOKEN");
return repository;
}
@Override
protected UserDetailsService userDetailsService() {
return customUserDetailsService;
}
@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
}
UserController中
@RequestMapping(method = RequestMethod.POST, value = "/authenticate")
@PreAuthorize("hasRole('ROLE_USER')")
public @ResponseBody User login(@RequestParam String username) {
User user = repo.getUserWithUsername(username);
if (user == null) throw new NotFoundException();
return user;
}
答案 0 :(得分:-1)
如果您有某种形式,请尝试此操作。 Spring会自动生成一个带有CSRF令牌的隐藏输入,您可以使用它:
function getCsrfHeader() {
var csrfToken = $("input[name='_csrf']").val();
var headers = {};
headers["X-CSRF-TOKEN"] = csrfToken;
headers["_csrf"] = csrfToken;
return headers;
};
function postSomethingToServer() {
var headers = getCsrfHeader();
var req = {
method: 'POST',
url: URL,
headers: headers,
data: SOME_DATA
};
$http(req)
.success(function() { ... })
.error(function() { ... });
}