基本身份验证不适用于 XSRF 令牌拦截
Basic authentication does not work with XSRF token interception
我正在实施一个简单的身份验证 API,它配置了 Spring Boot
,可以通过 Basic Auth
访问。这是一个简单的GET
API,没有任何参数,只用于强制浏览器触发认证window:
localhost:8080/api/auth
我从我的 Angular 7.3.10
项目中使用这个 API,该项目服务于
localhost:4200
同时,我正在使用 anti-CSRF
保护,因此我处理所有 API 调用,以便为 X-XSRF-TOKEN
添加一个额外的 header。这是我的 HttpInterceptor
:
export class CustomHttpInterceptor implements HttpInterceptor {
constructor(private xsrfTokenExtractor: HttpXsrfTokenExtractor) {
}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (req.url.startsWith(environment.apiUrl)) {
// send request with credential options in order to be able to read cross-origin cookies
req = req.clone({ withCredentials: true });
// return XSRF-TOKEN in each request's header (anti-CSRF security)
const headerName = 'X-XSRF-TOKEN';
let token = this.xsrfTokenExtractor.getToken() as string;
if (token !== null && !req.headers.has(headerName)) {
req = req.clone({ headers: req.headers.set(headerName, token) });
}
}
return next.handle(req);
}
}
现在,当我在我的 Angular 应用程序中调用身份验证端点时,我开始编写我的凭据,然后出现以下错误:
Access to XMLHttpRequest at 'http://localhost:8080/api/auth' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
在拦截我添加 XSRF token
的请求时有一个 preflight
请求并且此请求不包含 Basic Auth header
,即使我正确地提供了我的凭据:
现在,如果我从拦截器中删除添加 XSRF token
的部分,那么在我提供我的凭据后,授权请求将正常工作。当然它不需要XSRF token
,因为它是一个GET
请求,但将来我需要同时使用Basic Auth
和anti-CSRF
保护和POST API
调用,因此有必要使两者都起作用。有什么想法吗?
根据我的评论:
这是由于服务器端的 CORS
配置所致。
看起来 API 需要 OPTIONS
请求的凭据。但是,这些请求是由浏览器触发的,您无法修改它们以添加自定义 headers,就像您在屏幕截图中看到的那样...所以您的服务器 returns 401.
解决方案是修改 CORS 配置服务器端,以便 OPTIONS
请求不需要身份验证
我正在实施一个简单的身份验证 API,它配置了 Spring Boot
,可以通过 Basic Auth
访问。这是一个简单的GET
API,没有任何参数,只用于强制浏览器触发认证window:
localhost:8080/api/auth
我从我的 Angular 7.3.10
项目中使用这个 API,该项目服务于
localhost:4200
同时,我正在使用 anti-CSRF
保护,因此我处理所有 API 调用,以便为 X-XSRF-TOKEN
添加一个额外的 header。这是我的 HttpInterceptor
:
export class CustomHttpInterceptor implements HttpInterceptor {
constructor(private xsrfTokenExtractor: HttpXsrfTokenExtractor) {
}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (req.url.startsWith(environment.apiUrl)) {
// send request with credential options in order to be able to read cross-origin cookies
req = req.clone({ withCredentials: true });
// return XSRF-TOKEN in each request's header (anti-CSRF security)
const headerName = 'X-XSRF-TOKEN';
let token = this.xsrfTokenExtractor.getToken() as string;
if (token !== null && !req.headers.has(headerName)) {
req = req.clone({ headers: req.headers.set(headerName, token) });
}
}
return next.handle(req);
}
}
现在,当我在我的 Angular 应用程序中调用身份验证端点时,我开始编写我的凭据,然后出现以下错误:
Access to XMLHttpRequest at 'http://localhost:8080/api/auth' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
在拦截我添加 XSRF token
的请求时有一个 preflight
请求并且此请求不包含 Basic Auth header
,即使我正确地提供了我的凭据:
现在,如果我从拦截器中删除添加 XSRF token
的部分,那么在我提供我的凭据后,授权请求将正常工作。当然它不需要XSRF token
,因为它是一个GET
请求,但将来我需要同时使用Basic Auth
和anti-CSRF
保护和POST API
调用,因此有必要使两者都起作用。有什么想法吗?
根据我的评论:
这是由于服务器端的 CORS
配置所致。
看起来 API 需要 OPTIONS
请求的凭据。但是,这些请求是由浏览器触发的,您无法修改它们以添加自定义 headers,就像您在屏幕截图中看到的那样...所以您的服务器 returns 401.
解决方案是修改 CORS 配置服务器端,以便 OPTIONS
请求不需要身份验证