我正在Spring Boot + Angular 7应用程序中实现csrf,我担心的是当我进行登录时,我可以毫无问题地登录到该应用程序中。但是登录后csrf cookie没有更改,因此我从服务器收到403(CSRF已过期)错误,
但是当我刷新时它将正常工作。主要原因是cookie无法正确获取,我不知道问题出在哪里,例如来自客户端或服务器端。请帮助
我正在分享我的代码
Spring引导代码
@Override
protected void configure(HttpSecurity http) throws Exception {
http.httpBasic().and().csrf() // csrf config starts here
.csrfTokenRepository(csrfTokenRepository())
.ignoringAntMatchers("/", "/login", "/captcha-servlet", "/validateOTP", "supportApp/logout")
.and()
.addFilterAfter(new CustomCsrfFilter(), CsrfFilter.class);
}
private CsrfTokenRepository csrfTokenRepository() {
HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
repository.setHeaderName("X-XSRF-TOKEN");
return repository;
}
CSRF过滤器
public class CustomCsrfFilter 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();
cookie = new Cookie("XSRF-TOKEN", token);
cookie.setPath("/");
response.addCookie(cookie);
}
filterChain.doFilter(request, response);
}
}
CSRF角代码
import { HttpClient, HttpXsrfTokenExtractor, HttpHeaders } from '@angular/common/http';
constructor(private http: HttpClient, private tokenExtractor: HttpXsrfTokenExtractor) { }
const _csrf_token = this.tokenExtractor.getToken() as string;
return this.http.post(this._singleuserUrl, uid, {headers: new HttpHeaders().set('X-XSRF-TOKEN', _csrf_token), withCredentials: true});
答案 0 :(得分:1)
您似乎忘记了将 HttpClientXsrfModule 导入app.module.ts
在Angular 6中为我工作。
app.module.ts
imports: [
HttpClientXsrfModule.withOptions({
cookieName: "XSRF-TOKEN",
headerName: "X-XSRF-TOKEN"
}),
...
],
providers: [
{ provide: HTTP_INTERCEPTORS, useClass: HttpXSRFInterceptor, multi: true },
...
],
此外,我使用拦截器将令牌设置为HEADER
HttpXSRFInterceptor
@Injectable()
export class HttpXSRFInterceptor implements HttpInterceptor {
constructor(private tokenExtractor: HttpXsrfTokenExtractor) {
}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const headerName = 'XSRF-TOKEN';
const respHeaderName = 'X-XSRF-TOKEN';
let token = this.tokenExtractor.getToken() as string;
if (token !== null && !req.headers.has(headerName)) {
req = req.clone({ headers: req.headers.set(respHeaderName, token) });
}
return next.handle(req);
}
}
此外,您可以使用邮递员说明服务器中的配置是否正常。
希望它会有所帮助。