2016-03-29 61 views
11

私はです。角2アプリです。それはASP.NET 5(コア)の範囲内で実行されています。
正常に動作しているコントローラへのHttp呼び出しを行います。Angular2 ASP.NET Core AntiForgeryToken

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

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

注:Angularのデータ形式は、MVCビューでは作成されませんが、Angular2で完全に記述され、Webサービスのみを呼び出します。

私が見たすべての例は時代遅れであり、動作しない/完全に動作しません。

AntiForgeryTokenチェックをAngular2に統合するにはどうすればよいですか?フォームは純粋な角型ですか?

ありがとうございました。

答えて

6

カスタムアクションフィルタは必要ありません。それはすべて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

+0

上記の手順に従いましたが、400の不正なリクエストエラーが発生しています。私の "post"リクエストは "options:method type"としてサーバーに送られます。この問題に関する1つの質問 - https://stackoverflow.com/questions/44841588/antiforgery-token-implementation-in-angular-2-and- web-api-using-aps-net-core –

+0

私が今日発見したいくつかの追加情報 - IISでホストしている場合は、AntiForgeryTokenを生成するために使用するキーを維持するために、サーバー上でデータ保護を設定する必要があります。 、アプリケーションが再起動するとトークンが無効になります。設定方法についてはこちらを参照してください - https://docs.microsoft.com/en-us/aspnet/core/publishing/iis#data-protection – DanO

0

フォームの値の代わりにヘッダー経由でトークンを送信するカスタムAntiForgeryValidationToken属性を作成する必要があると思います。次に、あなたのAPIにあなたのAngular2アプリからのすべてのリクエストのヘッダーにトークンを追加します。

[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]追加:ここ How do you set global custom headers in Angular2?

0

例は、あなたがこのようなものを使用することができ、ヘッダーからトークンを検証します。ただし、これはMVC 5のASP.NET 4.5.2プロジェクトからのものですので、.NET Coreに合わせるために少し変更する必要があるかもしれません。また、トークンが見つからない場合にJSON結果を返すように修正しました。エラー応答を処理せずにユーザーに出力すると、その部分を削除できます。この属性のコア部分のため クレジットは、に行く:https://nozzlegear.com/blog/send-and-validate-an-asp-net-antiforgerytoken-as-a-request-header

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

+0

@ Html.AntiForgeryToken()を使用せずにトークンを作成する方法を知りましたか? – Jeremy

2

私はアクションフィルタを使用してリクエストトークンを送信しています。 新しい偽造防止トークンが必要なアクションに単に適用します。など

[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 { }); 
} 

Angular2 SPA、WebAPIのアクションは、スタートアップ内の属性を登録し、リクエストトークン形式 "X-XSRF-TOKEN" ヘッダを読み取ることAntiforgeryサービスを設定します。

public class Startup 
{ 
    // ... 

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

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

このアプローチをSPAで使用する方法に関する提案はありますか? GETアクションは実際にはヒットしません(/ Home/Indexを除く)、後でPOSTを行うすべてのフォームの新しいトークンをどのように配信しますか? –

+1

AngularAntiForgeryTokenAttributeをPOSTエンドポイントに適用してみてください。 POSTアクションでトークンを更新できるはずです。 – fszlin

関連する問題