AngularJS
的index.html
SpringSecurity 3.2
Spring使用HttpSessionCsrfTokenRepository,默认情况下为CSRF提供标题名称为 X-CSRF-TOKEN,但Anuglar约定为 X-XSRF-TOKEN
我想扩展HttpSessionCsrfTokenRepository并覆盖标题名称,但由于它标记为final,我最终实现了自定义标记库.
@Component public class CustomCsrfTokenRepository implements CsrfTokenRepository { public static final String CSRF_PARAMETER_NAME = "_csrf"; public static final String CSRF_HEADER_NAME = "X-XSRF-TOKEN"; private final MaptokenRepository = new ConcurrentHashMap<>(); public CustomCsrfTokenRepository() { log.info("Creating {}", CustomCsrfTokenRepository.class.getSimpleName()); } @Override public CsrfToken generateToken(HttpServletRequest request) { return new DefaultCsrfToken(CSRF_HEADER_NAME, CSRF_PARAMETER_NAME, createNewToken()); } @Override public void saveToken(CsrfToken token, HttpServletRequest request, HttpServletResponse response) { String key = getKey(request); if (key == null) return; if (token == null) { tokenRepository.remove(key); } else { tokenRepository.put(key, token); } } @Override public CsrfToken loadToken(HttpServletRequest request) { String key = getKey(request); return key == null ? null : tokenRepository.get(key); } private String getKey(HttpServletRequest request) { return request.getHeader("Authorization"); } private String createNewToken() { return UUID.randomUUID().toString(); } }
SecurityConfig.java
@Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Inject private CustomCsrfTokenRepository customCsrfTokenRepository; @Override protected void configure(HttpSecurity http) throws Exception { http // .addFilterAfter(new CsrfTokenGeneratorFilter(), CsrfFilter.class) .exceptionHandling() .authenticationEntryPoint(authenticationEntryPoint) .and() .formLogin() .loginProcessingUrl("/app/authentication") .successHandler(ajaxAuthenticationSuccessHandler) .failureHandler(ajaxAuthenticationFailureHandler) .usernameParameter("j_username") .passwordParameter("j_password") .permitAll() .and() .csrf() .csrfTokenRepository(customCsrfTokenRepository) .and() } }
如何干净地覆盖标题名称而不是创建自定义csrfTokenRepository?
我是否需要对单页应用程序(如AngularJS)进行任何其他配置更改,因为这还不起作用.
manish.. 11
在Spring Security中使用Java配置时,应该可以:
public void configure(final HttpSecurity http) throws Exception { final HttpSessionCsrfTokenRepository tokenRepository = new HttpSessionCsrfTokenRepository(); tokenRepository.setHeaderName("X-XSRF-TOKEN"); http.csrf().csrfTokenRepository(tokenRepository); }
复杂的是,单页应用程序依赖于AJAX,并且包含带有AJAX请求的CSRF令牌有点复杂.使用AngularJS时,服务器应该XSRF-TOKEN
在第一次请求时以及用户登录或注销时发送会话cookie .然后,AngularJS将在HTTP标头中返回此cookie的值以及X-XSRF-TOKEN
所有请求,然后服务器可以检查这些请求.
在Spring Security中使用Java配置时,应该可以:
public void configure(final HttpSecurity http) throws Exception { final HttpSessionCsrfTokenRepository tokenRepository = new HttpSessionCsrfTokenRepository(); tokenRepository.setHeaderName("X-XSRF-TOKEN"); http.csrf().csrfTokenRepository(tokenRepository); }
复杂的是,单页应用程序依赖于AJAX,并且包含带有AJAX请求的CSRF令牌有点复杂.使用AngularJS时,服务器应该XSRF-TOKEN
在第一次请求时以及用户登录或注销时发送会话cookie .然后,AngularJS将在HTTP标头中返回此cookie的值以及X-XSRF-TOKEN
所有请求,然后服务器可以检查这些请求.