使用 token API 和 angular 进行防伪
Anti forgery with token API and angular
我正在开发 Angular 6 具有 SSO 登录和 .net 核心 Web 的应用程序 API。代码第一次到达 /token url 上的后端,这是一个 post 操作。在这种情况下我如何进行防伪造。请解释代币转账流程
我不确定这是否是您要查找的内容,但我会尝试解释我是如何在类似案例中实现它的。
首先 Angular 内置了 XSRF 处理的助手:
- https://angular.io/guide/security#http
- https://angular.io/api/common/http/HttpClientXsrfModule
- https://angular.io/api/common/http/HttpXsrfTokenExtractor
所以最难的部分是在 api 级别创建自定义 XSRF 中间件。
我前一段时间为我的一个应用程序做了这件事,它是用 Angular 6 在前面构建的,ASP.NET Core WebApi 在 back-end.
对我有帮助的文章:
您的中间件可能如下所示:
public class AntiForgeryTokenMiddleware
{
private readonly RequestDelegate _next;
private readonly IAntiforgery _antiforgery;
public AntiForgeryTokenMiddleware(RequestDelegate next, IAntiforgery antiforgery)
{
_next = next;
_antiforgery = antiforgery;
}
public Task Invoke(HttpContext context)
{
if (context.Request.Path.Value.IndexOf("/your api endpoint, e.g. /api", StringComparison.OrdinalIgnoreCase) != -1)
{
var tokens = _antiforgery.GetAndStoreTokens(context);
context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken, new CookieOptions { HttpOnly = false, Secure = false });
}
return _next(context);
}
}
然后根据提到的文章,您必须将其添加到启动的 ConfigureServices 方法中的服务中 class:
services.AddAntiforgery(options => options.HeaderName = "X-XSRF-TOKEN");
并在配置方法中使用它:
app.UseAntiforgeryToken();
当然,要使用它,您必须使用 [ValidateAntiForgeryToken]
属性修饰 api 方法。
然后在您的 Angular 应用程序中,您可以创建 HttpInterceptor 以仅在需要时发送令牌。
@Injectable()
export class XsrfInterceptor implements HttpInterceptor {
constructor(private tokenExtractor: HttpXsrfTokenExtractor) {}
private actions: string[] = ["POST", "PUT", "DELETE"];
private forbiddenActions: string[] = ["HEAD", "OPTIONS"];
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
let token = this.tokenExtractor.getToken();
let permitted = this.findByActionName(request.method, this.actions);
let forbidden = this.findByActionName(request.method, this.forbiddenActions);;
if (permitted !== undefined && forbidden === undefined && token !== null) {
request = request.clone({ setHeaders: { "X-XSRF-TOKEN": token } });
}
return next.handle(request);
}
private findByActionName(name: string, actions: string[]): string {
return actions.find(action => action.toLocaleLowerCase() === name.toLocaleLowerCase());
}
}
这个问题很老,但我的解决方案可以帮助某些人。对我们有用的:
on Angular FE side HttpXsrfTokenInterceptor 用于设置 X-XSRF-TOKEN header。当然cookie必须包含XSRF-TOKEN
下的token
on .net core side:基本上是上面描述的方法,使用 domstamand's 方法。但是,这很重要,您必须将验证操作添加到中间件中。显然使用您的自定义 middlaware 关闭由 .net 核心防伪服务完成的 OOB 验证。因此,更新 Invoke 方法的代码后应如下所示:
public Task Invoke(HttpContext context)
{
if (context.Request.Headers.ContainsKey("X-XSRF-TOKEN"))
{
_antiForgery.ValidateRequestAsync(context);
}
var tokens = _antiForgery.GetAndStoreTokens(context);
context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken, new CookieOptions {
HttpOnly = false,
Secure = true
});
return _next(context);
}
我添加了检查 X-XSRF-TOKEN 以避免可能出现的问题,例如当调用 GET 或 OPTIONS 预检时。
更新:
我的解决方案的问题是,如果您不将 X-XSRF-TOKEN 包含到 HTTP 请求中,header 验证根本不会执行。我正在尝试解决这个问题。
我正在开发 Angular 6 具有 SSO 登录和 .net 核心 Web 的应用程序 API。代码第一次到达 /token url 上的后端,这是一个 post 操作。在这种情况下我如何进行防伪造。请解释代币转账流程
我不确定这是否是您要查找的内容,但我会尝试解释我是如何在类似案例中实现它的。
首先 Angular 内置了 XSRF 处理的助手:
- https://angular.io/guide/security#http
- https://angular.io/api/common/http/HttpClientXsrfModule
- https://angular.io/api/common/http/HttpXsrfTokenExtractor
所以最难的部分是在 api 级别创建自定义 XSRF 中间件。
我前一段时间为我的一个应用程序做了这件事,它是用 Angular 6 在前面构建的,ASP.NET Core WebApi 在 back-end.
对我有帮助的文章:
您的中间件可能如下所示:
public class AntiForgeryTokenMiddleware
{
private readonly RequestDelegate _next;
private readonly IAntiforgery _antiforgery;
public AntiForgeryTokenMiddleware(RequestDelegate next, IAntiforgery antiforgery)
{
_next = next;
_antiforgery = antiforgery;
}
public Task Invoke(HttpContext context)
{
if (context.Request.Path.Value.IndexOf("/your api endpoint, e.g. /api", StringComparison.OrdinalIgnoreCase) != -1)
{
var tokens = _antiforgery.GetAndStoreTokens(context);
context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken, new CookieOptions { HttpOnly = false, Secure = false });
}
return _next(context);
}
}
然后根据提到的文章,您必须将其添加到启动的 ConfigureServices 方法中的服务中 class:
services.AddAntiforgery(options => options.HeaderName = "X-XSRF-TOKEN");
并在配置方法中使用它:
app.UseAntiforgeryToken();
当然,要使用它,您必须使用 [ValidateAntiForgeryToken]
属性修饰 api 方法。
然后在您的 Angular 应用程序中,您可以创建 HttpInterceptor 以仅在需要时发送令牌。
@Injectable()
export class XsrfInterceptor implements HttpInterceptor {
constructor(private tokenExtractor: HttpXsrfTokenExtractor) {}
private actions: string[] = ["POST", "PUT", "DELETE"];
private forbiddenActions: string[] = ["HEAD", "OPTIONS"];
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
let token = this.tokenExtractor.getToken();
let permitted = this.findByActionName(request.method, this.actions);
let forbidden = this.findByActionName(request.method, this.forbiddenActions);;
if (permitted !== undefined && forbidden === undefined && token !== null) {
request = request.clone({ setHeaders: { "X-XSRF-TOKEN": token } });
}
return next.handle(request);
}
private findByActionName(name: string, actions: string[]): string {
return actions.find(action => action.toLocaleLowerCase() === name.toLocaleLowerCase());
}
}
这个问题很老,但我的解决方案可以帮助某些人。对我们有用的:
on Angular FE side HttpXsrfTokenInterceptor 用于设置 X-XSRF-TOKEN header。当然cookie必须包含XSRF-TOKEN
下的tokenon .net core side:基本上是上面描述的方法,使用 domstamand's 方法。但是,这很重要,您必须将验证操作添加到中间件中。显然使用您的自定义 middlaware 关闭由 .net 核心防伪服务完成的 OOB 验证。因此,更新 Invoke 方法的代码后应如下所示:
public Task Invoke(HttpContext context) { if (context.Request.Headers.ContainsKey("X-XSRF-TOKEN")) { _antiForgery.ValidateRequestAsync(context); } var tokens = _antiForgery.GetAndStoreTokens(context); context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken, new CookieOptions { HttpOnly = false, Secure = true }); return _next(context); }
我添加了检查 X-XSRF-TOKEN 以避免可能出现的问题,例如当调用 GET 或 OPTIONS 预检时。
更新: 我的解决方案的问题是,如果您不将 X-XSRF-TOKEN 包含到 HTTP 请求中,header 验证根本不会执行。我正在尝试解决这个问题。