Him*_*dar 2 csrf spring-security csrf-protection angularjs
AngularJS
的index.html
<head>
<meta name="_csrf" content="${_csrf.token}"/>
<!-- default header name is X-CSRF-TOKEN -->
<meta name="_csrf_header" content="${_csrf.headerName}"/>
</head>
Run Code Online (Sandbox Code Playgroud)
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 Map<String, CsrfToken> tokenRepository = 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();
}
}
Run Code Online (Sandbox Code Playgroud)
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()
}
}
Run Code Online (Sandbox Code Playgroud)
如何干净地覆盖标题名称而不是创建自定义csrfTokenRepository?
我是否需要对单页应用程序(如AngularJS)进行任何其他配置更改,因为这还不起作用.
man*_*ish 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);
}
Run Code Online (Sandbox Code Playgroud)
复杂的是,单页应用程序依赖于AJAX,并且包含带有AJAX请求的CSRF令牌有点复杂.使用AngularJS时,服务器应该XSRF-TOKEN在第一次请求时以及用户登录或注销时发送会话cookie .然后,AngularJS将在HTTP标头中返回此cookie的值以及X-XSRF-TOKEN所有请求,然后服务器可以检查这些请求.
| 归档时间: |
|
| 查看次数: |
7314 次 |
| 最近记录: |