2013-02-17 9 views
20

@ Html.AntiForgeryToken() rende input nascostoCome ottenere il valore AntiForgeryToken senza input nascosto

<input name="__RequestVerificationToken" type="hidden" value="GuiNIwhIJZjINHhuS_8FenaFDXIiaE" /> 

Come posso ottenere solo un valore simbolico? senza codice brutto come questo:

public static IHtmlString AntiForgeryTokenValue(this HtmlHelper htmlHelper) { 
     var field = htmlHelper.AntiForgeryToken().ToHtmlString(); 
     var beginIndex = field.IndexOf("value=\"") + 7; 
     var endIndex = field.IndexOf("\"", beginIndex); 
     return new HtmlString(field.Substring(beginIndex, endIndex - beginIndex)); 
    } 

risposta

13

Le funzionalità anti-CSRF di MVC in realtà dipendono due gettoni: uno è un elemento di forma nascosta, e l'altro è un cookie. Quindi l'helper Html.AntiForgeryToken() non restituisce solo uno snippet HTML. Ha anche un effetto collaterale sull'impostazione di questo cookie. Si noti che il valore del cookie e il valore del modulo non sono uguali poiché codificano ciascuno pezzi di informazione diversi.

Se si utilizza l'API AntiForgery.GetTokens, questo metodo restituirà i token non elaborati invece di generare uno snippet HTML. I parametri di questo metodo sono:

  • oldCookieToken: Se la richiesta contiene già un cookie di token anti-CSRF, forniscono qui. Questo parametro potrebbe essere nullo.
  • newCookieToken (parametro out): Se oldCookieToken era nullo o non rappresentava un cookie di token anti-CSRF valida, questo parametro verrà popolato con il valore che si dovrebbe mettere nel cookie di risposta. Se oldCookieToken rappresenta un token anti-CSRF valido, quindi newCookieToken conterrà null quando il metodo restituisce e non è necessario impostare un cookie di risposta.
  • formToken (parametro out): Questo parametro verrà popolato con il token che deve essere presente nel corpo del modulo durante la registrazione sul server. Questo è il valore che finisce per essere avvolto dall'elemento di input nascosto in una chiamata a Html.AntiForgeryToken().

Se si utilizza questa API per generare cookie e forma gettoni manualmente, è necessario chiamare the corresponding overload di AntiForgery.Validate al fine di convalidare i token.

+3

che so di effetto collaterale, ma la mia domanda è di circa applicazione js complesso senza alcuna forma HTML. Sto inviando una richiesta jax per ottenere token modulo e token cookie, dopodiché, ho appena inviato la mia richiesta Ajax con un token modulo. Ma ora non conosco il modo carino e semplice per impostare cookie e ottenere un token modulo senza l'analisi junk html. –

+3

Ho scoperto che l'esposizione del 'Nome' e' Valore' del token modulo anti-falsificazione generato in 'HtmlHelper' è necessario per essere utilizzato in Javascript come il framework ExtJs. Non posso semplicemente scrivere elementi HTML, ma ho bisogno di estendere il componente ExtJs e gestire il modello lato client o utilizzare l'Hiddenfield esistente che richiede solo nome e valore anziché l'intero elemento di input ... 'AntiForgery.GetTokens': richiede di giocare con i cookie; 'AntiForgery.Validate': già internamente chiamato dall'attributo' [ValidateAntiForgeryToken] '... Concludo utilizzando l'estensione OP HtmlHelper per ottenere il nome e il valore. – CallMeLaNN

10

Mi rendo conto che questa domanda è vecchia, ma sulla base di ciò che ho letto qui ho trovato una soluzione ragionevolmente semplice che sembra funzionare per me. Lo sto utilizzando su AngularJS SPA che utilizza modelli parziali, solo alcuni dei quali prevedono l'invio di POST.

ho messo questo codice nella parte superiore di vista:

@{ 
    string cookieToken, formToken; 
    string oldCookieToken = Request.Cookies[AntiForgeryConfig.CookieName] == null ? null : Request.Cookies[AntiForgeryConfig.CookieName].Value; 
AntiForgery.GetTokens(oldCookieToken, out cookieToken, out formToken); 

    if(oldCookieToken == null) 
    { 
     Request.Cookies.Add(new HttpCookie(AntiForgeryConfig.CookieName,  cookieToken)); 
    } 
    else 
    { 
     Request.Cookies[AntiForgeryConfig.CookieName].Value = cookieToken; 
    } 
} 

e poi ovunque ho bisogno di token antiforgery del form (ad esempio, in un Ajax o angularjs POST) Ho appena includono '@formToken' nelle intestazioni :

$http.post(route, JSON.stringify(args), { 
    headers: { 
     '@AntiForgeryConfig.CookieName': '@formToken', 
     'Content-Type': 'application/json; charset=utf-8', 
    }, 
}); 

Nota che perché in questo esempio mi aspetto i dati JSON indietro dal mio metodo di azione ho dovuto anche ad attuare la convalida anti-contraffazione sulla base di intestazioni, non formano i campi. C'è un bel post su questo allo http://johan.driessen.se/posts/Updated-Anti-XSRF-Validation-for-ASP.NET-MVC-4-RC..Ecco l'implementazione:

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

     var httpContext = filterContext.HttpContext; 
     var cookie = httpContext.Request.Cookies[AntiForgeryConfig.CookieName]; 
     AntiForgery.Validate(cookie != null ? cookie.Value : null, 
          httpContext.Request.Headers[AntiForgeryConfig.CookieName]); 
    } 
} 

ed ecco come viene utilizzato:

[HttpPost] 
    [ValidateJsonAntiForgeryToken] 
    public JsonResult RecordVisit(VisitInfo info) 
Problemi correlati