2016-03-29 14 views
11

मेरे पास कोणीय 2 ऐप है। यह एएसपी.NET 5 (कोर) के भीतर चल रहा है।
यह एचटीपी नियंत्रक को कॉल करता है जो ठीक काम कर रहा है।कोणीय 2 एएसपी.नेट कोर एंटीफोर्गेरी टोकन

लेकिन अब मुझे क्रॉस साइट स्क्रिप्टिंग प्रक्षेपण स्थापित करने की आवश्यकता है।

मैं प्रत्येक एचटीपी अनुरोध पर एक नया टोकन कैसे उत्पन्न करूं और फिर बाद में Angular2 ऐप्स में एंटीफोर्गेरी टोकन चेक निष्पादित करूं?

नोट: कोणीय में मेरा डेटा रूप एमवीसी व्यू से नहीं बनाया गया है लेकिन पूरी तरह से कोणीय 2 में लिखा गया है और केवल वेब सेवाओं को कॉल करता है।

मेरे द्वारा देखे गए सभी उदाहरण दिनांकित हैं और काम नहीं करते/पूरी तरह से काम नहीं करते हैं।

एएसपी.नेट 5 के खिलाफ कोणीय 2 में एंटीफोर्गेरी टोकन चेक को मैं कैसे एकीकृत करूं, जहां फॉर्म शुद्ध कोणीय हैं?

धन्यवाद।

उत्तर

6

एक कस्टम एक्शन फ़िल्टर आवश्यक नहीं है। इसे स्टार्टअप सीएस में तारित किया जा सकता है।

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 खराब अनुरोध त्रुटि मिल रही है। मेरा "पोस्ट" अनुरोध सर्वर पर "विकल्प: विधि प्रकार के रूप में जाता है। मैंने इस मुद्दे के बारे में एक प्रश्न पूछा- https://stackoverflow.com/questions/44841588/antiforgery-token-implementation-in-angular-2-and- वेब-एपीआई-यूपी-नेट-कोर –

+0

आज मैंने कुछ अतिरिक्त जानकारी खोजी - यदि आप आईआईएस में होस्टिंग कर रहे हैं, तो आपको एंटीफॉर्गेरी टोकन जेनरेट करने के लिए उपयोग की जाने वाली कुंजियों को बनाए रखने के लिए सर्वर पर डेटा प्रोटेक्शन कॉन्फ़िगर करना चाहिए। अगर आप नहीं करते हैं , जब ऐप पुनरारंभ होता है तो टोकन अमान्य हो जाएंगे। कॉन्फ़िगर करने के तरीके के बारे में जानकारी के लिए यहां देखें - https://docs.microsoft.com/en-us/aspnet/core/publishing/iis#data-protection – DanO

0

मुझे लगता है कि आपको कस्टम एंटीफ़ोर्गेरी वैलिडेशन टोकन विशेषता बनाने की आवश्यकता है जो फॉर्म मानों के बजाय शीर्षलेख के माध्यम से टोकन भेजने का समर्थन करता है। फिर अपने एंगुलर 2 ऐप से अपने एपीआई के प्रत्येक अनुरोध के शीर्षलेख पर टोकन जोड़ें। यहाँ How do you set global custom headers in Angular2?

0

उदाहरण सिर से टोकन प्रमाणित करने के लिए आप कुछ इस तरह का उपयोग कर सकते हैं:

[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] अपने नियंत्रक में तरीकों पर। नोट हालांकि, यह एक एमवीसी 5, एएसपी.NET 4.5.2 प्रोजेक्ट से है, इसलिए आपको इसे .NET कोर में समायोजित करने के लिए थोड़ा बदलना पड़ सकता है। टोकन गुम होने पर भी मैंने JSON परिणाम लौटने के लिए इसे संशोधित किया है, यदि आप त्रुटि प्रतिक्रिया को संभाल नहीं पाते हैं और इसे उपयोगकर्ता को आउटपुट करते हैं तो आप उस भाग को निकाल सकते हैं। इस विशेषता के मुख्य भाग के लिए क्रेडिट को जाता है: https://nozzlegear.com/blog/send-and-validate-an-asp-net-antiforgerytoken-as-a-request-header

कठिन हिस्सा कैसे शुद्ध कोणीय 2 आवेदन में @Html.AntiForgeryToken() का उपयोग कर (उपयोग के बिना फ़ाइलों .cshtml करने के लिए) के बिना AntiForgeryToken उत्पन्न करने के लिए है। मैं इसके जवाब भी ढूंढ रहा हूं।

+0

मुझे आश्चर्य है कि क्या आपको कभी भी @ Html.AntiForgeryToken() का उपयोग किए बिना टोकन बनाने का उत्तर मिला है? – Jeremy

2

मैं अनुरोध टोकन भेजने के लिए एक एक्शन फ़िल्टर का उपयोग कर रहा हूं। बस इसे उन क्रियाओं पर लागू करें जिन्हें आप एक नया एंटीफॉर्गेरी टोकन चाहते हैं, उदा। Angular2 एसपीए, वेबएपीआई कार्रवाई, आदि

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

स्टार्टअप में विशेषता रजिस्टर, और Antiforgery सेवा को कॉन्फ़िगर अनुरोध टोकन प्रपत्र "एक्स-XSRF-टोकन" शीर्षक को पढ़ने के लिए।

public class Startup 
{ 
    // ... 

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

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

एसपीए में इस दृष्टिकोण का उपयोग करने के तरीके पर कोई सुझाव? जीईटी क्रियाएं व्यावहारिक रूप से हिट नहीं होतीं (सिवाय/होम/इंडेक्स), आप प्रत्येक फॉर्म के लिए एक नया टोकन कैसे वितरित करते हैं जो बाद में पोस्ट करेगा? –

+1

अपने पोस्ट एंडपॉइंट्स पर AngularAntiForgeryTokenAttribute को लागू करने का प्रयास करें। आपको POST क्रियाओं में टोकन को नवीनीकृत करने में सक्षम होना चाहिए। – fszlin

संबंधित मुद्दे