提问人:jonantony 提问时间:11/9/2023 更新时间:11/9/2023 访问量:34
Angular 中的 XSRF/CSRF 保护 - xsrfTokenExtractor.getToken();返回 null
XSRF/CSRF protection in Angular - xsrfTokenExtractor.getToken(); returns null
问:
.NET 7 WebAPI + Angular 前端。
来自 API 调用的示例响应标头:
Access-Control-Allow-Origin:
*
Cache-Control:
no-cache, no-store
Content-Type:
application/problem+json; charset=utf-8
Date:
Wed, 08 Nov 2023 16:45:15 GMT
Pragma:
no-cache
Server:
Kestrel
Set-Cookie:
XSRF-TOKEN=XXXXXXXXXXXXX; path=/
Set-Cookie:
XSRF-TOKEN=XXXXXXXXXXXXX; path=/; samesite=strict; httponly
X-Frame-Options:
SAMEORIGIN
响应状态代码: 。当然是实际的代币。400 Bad Request
XXXXXXXXXXXXX
请求标头:
:authority:
localhost:7129
:method:
POST
:path:
/mycontroller/myendpoint
:scheme:
https
Accept:
application/json, text/plain, */*
Accept-Encoding:
gzip, deflate, br
Accept-Language:
pl-US,pl;q=0.9,en-US;q=0.8,en;q=0.7,es;q=0.6
Cache-Control:
no-cache
Content-Length:
11
Content-Type:
application/json
Origin:
http://localhost:4210
Pragma:
no-cache
Referer:
http://localhost:4210/
Sec-Ch-Ua:
"Google Chrome";v="119", "Chromium";v="119", "Not?A_Brand";v="24"
Sec-Ch-Ua-Mobile:
?0
Sec-Ch-Ua-Platform:
"Windows"
Sec-Fetch-Dest:
empty
Sec-Fetch-Mode:
cors
Sec-Fetch-Site:
cross-site
User-Agent:
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36
如您所见,请求中没有任何与 XSRF/CSRF 保护相关的内容,这就是我的端点安全返回的原因[ValidateAntiForgeryToken]
400
XSRF 拦截器(角度):
@Injectable()
export class XsrfInterceptor implements HttpInterceptor {
constructor(private xsrfTokenExtractor: HttpXsrfTokenExtractor) {
}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
let xsrfToken = this.xsrfTokenExtractor.getToken();
if (xsrfToken != null) {
const authorizedRequest = req.clone({
withCredentials: true,
headers: req.headers.set('X-XSRF-TOKEN', xsrfToken)
});
return next.handle(authorizedRequest);
} else {
return next.handle(req);
}
}
}
在 app.module.ts 中:
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: AuthInterceptor,
multi: true,
},
{ provide: HTTP_INTERCEPTORS, useClass: XsrfInterceptor, multi: true }
],
的值是let xsrfToken = this.xsrfTokenExtractor.getToken();
null
程序.cs(后端):
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddApplication()
.AddInfrastructure(builder.Configuration);
builder.Services.AddEndpointsApiExplorer();
var audience = builder.Configuration.GetValue<string>("FpId");
builder.Services.AddAuthentication(o =>
{
o.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
o.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
o.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(o =>
{
o.RefreshOnIssuerKeyNotFound = true;
o.MetadataAddress = $"https://securetoken.google.com/{audience}/.well-known/openid-configuration";
o.Audience = audience;
});
builder.Services.AddCors(options =>
{
options.AddPolicy(name: "MyCors",
builder =>
{
builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
});
});
builder.Services.AddAuthorization();
builder.Services.AddAntiforgery(options =>
{
options.HeaderName = "X-XSRF-TOKEN";
options.Cookie.Name = "XSRF-TOKEN";
});
builder.Services.AddControllersWithViews(options =>
{
options.Filters.Add(new Microsoft.AspNetCore.Mvc.ValidateAntiForgeryTokenAttribute());
});
var app = builder.Build();
app.UseCors("MyCors");
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();
var antiforgery = app.Services.GetRequiredService<IAntiforgery>();
app.Use((context, next) =>
{
var requestPath = context.Request.Path.Value;
var tokenSet = antiforgery.GetAndStoreTokens(context);
context.Response.Cookies.Append("XSRF-TOKEN", tokenSet.RequestToken!,
new CookieOptions { HttpOnly = false });
return next(context);
});
app.MapControllers();
app.Run();
为什么?
我的 API 被“托管”(在我的 PC 上本地),而 Angular 打开 - 这会有问题吗?https://localhost:7129
http://127.0.0.1:4210/
答: 暂无答案
评论