Anti forgery system on ASP.Net MVC

后端 未结 2 1571
忘掉有多难
忘掉有多难 2021-02-08 06:22

When I\'m putting following code:

 @using (Html.BeginForm(\"LogOff\", \"Account\", FormMethod.Post, new { id = \"logoutForm\" }))
    {
        @Html.AntiForgery         


        
相关标签:
2条回答
  • 2021-02-08 07:02

    It's telling you that it won't work because despite being logged in, Membership.GetUser().UserName is not providing a name that can be used for hashing.

    So your real problem is, "How come my logged in user doesn't have a username?"

    0 讨论(0)
  • 2021-02-08 07:14

    There can be some cases when logged in user doesn't have Identity.Name set (in my case I have to integrate my app with some crazy log-in system). Then there are two ways around:

    1) unsecure - all users will be treated the same way by antiforgery system regardless of their auth status

    // System.Web.WebPages.dll
    using System.Web.Helpers;
    
    // not a production solution
    public class MvcApplication : HttpApplication {
      protected void Application_Start() {
        AntiForgeryConfig.SuppressIdentityHeuristicChecks = true;
      }
    }
    

    2) secure - provide your own (custom) way how you distinguish your users

    using System;
    using System.Globalization;
    using System.Web;
    using System.Web.Helpers;
    
    public class ContoscoAntiForgeryAdditionalDataProvider : IAntiForgeryAdditionalDataProvider {
      public string GetAdditionalData(HttpContextBase context) {
        if (context == null) {
          throw new ArgumentNullException("context");
        }
    
        var contoscoContext = new ContoscoHttpContext(context);
        int userID = contoscoContext.GetUserID().GetValueOrDefault();
        return Convert.ToString(userID, CultureInfo.InvariantCulture);
      }
    
      public bool ValidateAdditionalData(HttpContextBase context, string additionalData) {
        string data = GetAdditionalData(context);
        return string.Compare(data, additionalData, StringComparison.Ordinal) == 0;
      }
    }
    
    
    public class MvcApplication : HttpApplication {
      protected void Application_Start() {
        AntiForgeryConfig.AdditionalDataProvider = 
          new ContoscoAntiForgeryAdditionalDataProvider(); 
      }
    }
    

    where ContoscoHttpContext is class that returns UserID (or any unique user token) based on current context (i.e. HttpContextBase):

    public class ContoscoHttpContext {
      private HttpContextBase _context;
      public ContoscoHttpContext(HttpContextBase context) {
        _context = context;
      }
      public int? GetUserID() {
        // TODO: provide your own implementation how to get user id
        // based on HttpContextBase stored in _context
        // in my case it was something like 
        // return ((ContoscoPrincipal)_context.User).UserID;
      }
    }
    
    0 讨论(0)
提交回复
热议问题