Asp.net-Mvc-3

在 MVC3 中使用自定義 IPrincipal 和 IIdentity

  • May 24, 2012

我創建了自己的IPrincipal實現IIdentity,如下所示:

[ComVisible(true)]
[Serializable]
public sealed class CustomIdentity : IIdentity {

   private readonly string _name;
   private readonly string _email;
   // and other stuffs

   public CustomIdentity(string name) {
       _name = name.Trim();
       if(string.IsNullOrWhiteSpace(name))
           return;
       _email = (connect to database and read email and other stuffs);
   }

   public string Name {
       get { return _name; }
   }

   public string Email {
       get { return _email; }
   }

   public string AuthenticationType {
       get { return "CustomIdentity"; }
   }

   public bool IsAuthenticated {
       get { return !string.IsNullOrWhiteSpace(_name); }
   }

}


[ComVisible(true)]
[Serializable]
public sealed class CustomPrincipal : IPrincipal {

   private readonly CustomIdentity _identity;

   public CustomPrincipal(CustomIdentity identity) {
       _identity = identity;
   }

   public bool IsInRole(string role) {
       return _identity != null && 
              _identity.IsAuthenticated &&
              !string.IsNullOrWhiteSpace(role) &&
              Roles.IsUserInRole(_identity.Name, role);
   }

   IIdentity IPrincipal.Identity {
       get { return _identity; }
   }

   public CustomIdentity Identity {
       get { return _identity; }
   }

}

另外,我創建了一個HttpModule並且在它的AuthenticateRequest事件中,我這樣做:

   public void Init(HttpApplication context) {
       _application = context;
       _application.AuthenticateRequest += ApplicationAuthenticateRequest;
   }

   private void ApplicationAuthenticateRequest(object sender, EventArgs e) {
       var formsCookie = _application.Request.Cookies[FormsAuthentication.FormsCookieName];
       var identity = formsCookie != null
            ? new CustomIdentity(FormsAuthentication.Decrypt(formsCookie.Value).Name)
            : new CustomIdentity(string.Empty);
       var principal = new CustomPrincipal(identity);
       _application.Context.User = Thread.CurrentPrincipal = principal;
   }

另外,我創建了自己的ControllerWebViewPage喜歡這些:

public abstract class CustomController : Controller {
   public new CustomPrincipal User {
       get {
           var user = System.Web.HttpContext.Current.User as CustomPrincipal;
           return user;
       }
   }
}


public abstract class CustomWebViewPage<TModel> : WebViewPage<TModel> {
   public new CustomPrincipal User {
       get {
           // (Place number 1) here is the error I'm speaking about!!!
           var user = HttpContext.Current.User as CustomPrincipal;
           return user;
       }
   }
}

如上面的程式碼所示,似乎一切都是正確的;但正如您所見,在1 號位置我無法訪問CustomPrincipal!意味著在這個地方,我有 aRolePrincipal而不是CustomPrincipal. egHttpContext.Current.User是 aRolePrincipal而不是CustomPrincipal. 但RolePrincipal.Identity屬性是CustomIdentity

你的錯誤在這裡:

_application.AuthenticateRequest += ApplicationAuthenticateRequest;

有一個HttpModule命名RoleManagerModule的方法呼叫 inHttpApplication.PostAuthenticateRequest並將其設置HttpContext.Current.UserRolePrincipal。因此,您正在設置UserinAuthenticateRequestRoleManagerModuleset in PostAuthenticateRequest,這意味著在您的設置之後,因此會覆蓋您的設置。改變你的Module.Init

public void Init(HttpApplication context) {
   _application = context;
   // change just this line:
   _application.PostAuthenticateRequest += ApplicationAuthenticateRequest;
}

重要更新:

如果這個問題不起作用,請參閱這個問題- 由初學者再次提出,取決於目前問題 - 以獲得第二個解決方案。

引用自:https://stackoverflow.com/questions/10742259