web-dev-qa-db-ja.com

Angular2ASP.NETコアAntiForgeryToken

Angular2アプリがあります。 ASP.NET 5(コア)内で実行されています。
正常に動作しているコントローラーにHttp呼び出しを行います。

しかし今、私はクロスサイトスクリプティングの予測を確立する必要があります。

各Httpリクエストで新しいトークンを生成し、その後Angular2アプリでAntiForgeryTokenチェックを実行するにはどうすればよいですか?

注:AngularのデータフォームはMVCビューから生成されるのではなく、完全にAngular2で記述され、Webサービスのみを呼び出します。

私が見たすべての例は古く、機能しない/完全に機能しません。

フォームが純粋なAngularであるASP.NET5に対してAntiForgeryTokenチェックをAngular2に統合するにはどうすればよいですか?

ありがとう。

14
DanAbdn

カスタムアクションフィルターは必要ありません。すべてStartup.csに接続できます。

using Microsoft.AspNetCore.Antiforgery;

(...)

public void ConfigureServices(IServiceCollection services)
{
  services.AddAntiforgery(options => options.HeaderName = "X-XSRF-TOKEN");

  (...)
}

public void Configure(IApplicationBuilder app, IAntiforgery antiforgery)
{
  app.Use(next => context =>
  {
    if (context.Request.Path == "/")
    {
      //send the request token as a JavaScript-readable cookie, and Angular will use it by default
      var tokens = antiforgery.GetAndStoreTokens(context);
      context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken, new CookieOptions { HttpOnly = false });
    }
    return next(context);
  });

  (...)
}

次に、コントローラーに必要なのは、トークンが提供されることを強制したい場所にある[ValidateAntiForgeryToken]デコレーターだけです。

参考までに、このソリューションをここで見つけました AspNet AntiForgery Github Issue 29

6
DanO

アクションフィルターを使用してリクエストトークンを送信しています。新しい偽造防止トークンが必要なアクションに適用するだけです。 Angular2 SPA、WebAPIアクションなど。

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
public class AngularAntiForgeryTokenAttribute : ActionFilterAttribute
{
    private const string CookieName = "XSRF-TOKEN";
    private readonly IAntiforgery antiforgery;

    public AngularAntiForgeryTokenAttribute(IAntiforgery antiforgery)
    {
        this.antiforgery = antiforgery;
    }

    public override void OnResultExecuting(ResultExecutingContext context)
    {
        base.OnResultExecuting(context);

        if (!context.Cancel)
        {
            var tokens = antiforgery.GetAndStoreTokens(context.HttpContext);

            context.HttpContext.Response.Cookies.Append(
                CookieName,
                tokens.RequestToken,
                new CookieOptions { HttpOnly = false });
        }
    }
}
/* HomeController */

[ServiceFilter(typeof(AngularAntiForgeryTokenAttribute), IsReusable = true)]
public IActionResult Index()
{
    return View();
}

/* AccountController */

[HttpPost()]
[AllowAnonymous]
[ValidateAntiForgeryToken]
// Send new antiforgery token
[ServiceFilter(typeof(AngularAntiForgeryTokenAttribute), IsReusable = true)]
public async Task<IActionResult> Register([FromBody] RegisterViewModel model)
{
    //...
    return Json(new { }); 
}

スタートアップに属性を登録し、リクエストトークンフォーム「X-XSRF-TOKEN」ヘッダーを読み取るようにAntiforgeryサービスを構成します。

public class Startup
{
    // ...

    public void ConfigureServices(IServiceCollection services)
    {
        // ...

        services.AddScoped<AngularAntiForgeryTokenAttribute>();
        services.AddAntiforgery(options =>
        {
            options.HeaderName = "X-XSRF-TOKEN";
        });
    }
}
4
fszlin

フォーム値の代わりにヘッダーを介したトークンの送信をサポートするカスタムAntiForgeryValidationToken属性を作成する必要があると思います。次に、Angular2アプリからAPIへのすべてのリクエストのヘッダーにトークンを追加します。ここでの例 Angular2でグローバルカスタムヘッダーをどのように設定しますか?

0
Wanton

ヘッダーからトークンを検証するには、次のようなものを使用できます。

_[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
    public sealed class ValidateHeaderAntiForgeryTokenAttribute : FilterAttribute, IAuthorizationFilter
    {
        public void OnAuthorization(AuthorizationContext filterContext)
        {
            if (filterContext == null)
            {
                throw new ArgumentNullException(nameof(filterContext));
            }

            var httpContext = filterContext.HttpContext;
            if (httpContext.Request.Headers["__RequestVerificationToken"] == null)
            {
                httpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
                httpContext.Response.StatusDescription = "RequestVerificationToken missing.";

                filterContext.Result = new JsonResult
                {
                    Data = new { ErrorMessage = httpContext.Response.StatusDescription },
                    JsonRequestBehavior = JsonRequestBehavior.AllowGet
                };
                return;
            }
            var cookie = httpContext.Request.Cookies[System.Web.Helpers.AntiForgeryConfig.CookieName];
            System.Web.Helpers.AntiForgery.Validate(cookie != null ? cookie.Value : null, httpContext.Request.Headers["__RequestVerificationToken"]);
        }
    }
_

次に、コントローラーのメソッドに[ValidateHeaderAntiForgeryToken]を追加するだけです。ただし、これはMVC 5、ASP.NET 4.5.2プロジェクトからのものであるため、.NETCoreに合わせるために少し変更する必要がある場合があります。また、トークンが欠落している場合にJSON結果を返すようにこれを変更しました。エラー応答を処理しない場合は、その部分を削除してユーザーに出力できます。この属性のコア部分のクレジットは次のようになります: https://nozzlegear.com/blog/send-and-validate-an-asp-net-antiforgerytoken-as-a-request-header

難しい部分は、純粋なAngular 2アプリケーション(.cshtmlファイルへのアクセスなし)で@Html.AntiForgeryToken()を使用せずにAntiForgeryTokenを生成する方法です。私はその答えを探しています同様に。

0
hug