2017-11-01 25 views
2

私はIAntiforgery apisを使用してASP.Net Core 2アプリケーションを作成しました。提供された偽造防止トークンの検証に失敗しました。 Cookieトークンとリクエストトークンが交換されました

これは、実行するクッキーを返すメソッドを提供します。

クライアントはそのCookieを受け取り、それ以降のPOST要求では、値をX-XSRF-TOKENヘッダーに入れます。

ミドルウェアはこれを検証し、失敗した場合にリクエストを続行するかどうかを許可します。

リクエストで送信された正しいCookieとヘッダーは、常に検証に失敗し、理由を理解できません。

全体の再現はしかし、主な問題領域は以下の通りですここhttps://github.com/jchannon/AntiForgery

です。

antiforgeryのソースコードといくつかの悪い名前のメソッド(私はあなたを見てい SetCookieTokenAndHeader)に飛び込むの後にそう
public class Startup 
{ 
    public void Configure(IApplicationBuilder app, IAntiforgery antiforgery, ILoggerFactory loggerFactory) 
    { 
     app.UseAuthentication(); 

     app.Use(async (context, next) => 
     { 
      var logger = loggerFactory.CreateLogger("ValidRequestMW"); 

      //Don't validate POST for login 
      if (context.Request.Path.Value.Contains("login")) 
      { 
       await next(); 
       return; 
      } 

      logger.LogInformation(context.Request.Cookies["XSRF-TOKEN"]); 
      logger.LogInformation(context.Request.Headers["X-XSRF-TOKEN"]); 

      //On POST requests it will validate the XSRF header 
      if (!await antiforgery.IsRequestValidAsync(context)) 
      { 

       /**************************************************** 
       * 
       * 
       * For some reason when the cookie and the header are sent in on the /create POST this validation always fails 
       * 
       * 
       ***************************************************/ 
       context.Response.StatusCode = 401; 

       logger.LogError("INVALID XSRF TOKEN"); 
       return; 
      } 
      await next(); 
     }); 

     app.UseRouter(r => 
     { 
      r.MapGet("", async context => { await context.Response.WriteAsync("hello world"); }); 

      //This returns a XSRF-TOKEN cookie 
      //Client will take this value and add it as a X-XSRF-TOKEN header and POST to /create 
      r.MapPost("login", async (context) => 
      { 
       antiforgery.SetCookieTokenAndHeader(context); 
       context.Response.Redirect("/"); 
      }); 

      //If XSRF validaiton is correct we should hit this route 
      r.MapPost("create", async context => 
      { 
       context.Response.StatusCode = 201; 
       await context.Response.WriteAsync("Created"); 
      }); 
     }); 
    } 

    public void ConfigureServices(IServiceCollection services) 
    { 
     services.AddLogging(x => x.AddConsole()); 

     services.AddAntiforgery(options => 
     { 
      options.HeaderName = "X-XSRF-TOKEN"; 
      options.Cookie.Name = "XSRF-TOKEN"; 
      options.Cookie.HttpOnly = false; 
     }); 

//  services.AddAuthentication("MyCookieMW") 
//    .AddCookie("MyCookieMW", cookieOptions => 
//    { 
//     cookieOptions.Cookie.Name = "MyCookie"; 
//     cookieOptions.Cookie.HttpOnly = true; 
//     cookieOptions.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest; 
//     cookieOptions.SlidingExpiration = true; 
//    }); 

     services.AddRouting(); 
    } 
} 

答えて

1

。正しいコードは次のとおりです。

public void Configure(IApplicationBuilder app, IAntiforgery antiforgery, ILoggerFactory loggerFactory) 
    { 
     app.Use(async (context, next) => 
     { 
      var logger = loggerFactory.CreateLogger("ValidRequestMW"); 

      //Don't validate POST for login 
      if (context.Request.Path.Value.Contains("login")) 
      { 
       await next(); 
       return; 
      } 

      logger.LogInformation("Request Cookie is " + context.Request.Cookies["XSRF-TOKEN"]); 
      logger.LogInformation("Request Header is " + context.Request.Headers["X-XSRF-TOKEN"]); 

      //On POST requests it will validate the XSRF header 
      if (!await antiforgery.IsRequestValidAsync(context)) 
      { 
       context.Response.StatusCode = 401; 

       logger.LogError("INVALID XSRF TOKEN"); 
       return; 
      } 
      await next(); 
     }); 

     app.UseRouter(r => 
     { 
      r.MapGet("", async context => { await context.Response.WriteAsync("hello world"); }); 

      //This returns a XSRF-TOKEN cookie 
      //Client will take this value and add it as a X-XSRF-TOKEN header and POST to /create 
      r.MapPost("login", async (context) => 
      { 
       var tokens = antiforgery.GetAndStoreTokens(context); 
       context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken, 
        new CookieOptions() { HttpOnly = false }); 
       context.Response.Redirect("/"); 
      }); 

      //If XSRF validaiton is correct we should hit this route 
      r.MapPost("create", async context => 
      { 
       context.Response.StatusCode = 201; 
       await context.Response.WriteAsync("Created"); 
      }); 
     }); 
    } 

    public void ConfigureServices(IServiceCollection services) 
    { 
     services.AddSingleton<IAntiforgeryTokenGenerator, MyTokenGenerator>(); 
     services.AddSingleton<IAntiforgery, MyAntiforgery>(); 

     services.AddLogging(x => x.AddConsole()); 

     services.AddAntiforgery(options => 
     { 
      options.HeaderName = "X-XSRF-TOKEN"; 
      options.Cookie.Name = "MyAntiforgery"; 
      options.Cookie.HttpOnly = false; 
     }); 

     services.AddRouting(); 
    } 
関連する問題