Custom principal in ASP.NET MVC

做~自己de王妃 提交于 2019-12-04 13:45:48

I wanted to throw out an alternative idea just so people looking for this information can have some choices.

I went searching for a viable FormsAuthenticationTicket example and found that NerdDinner does a pretty decent job adding custom properties without impacting unit testing.

In my case, I modified my LogOn routine (which I was already mocking in my unit tests) to create a FormsAuthenticationTicket. NerdDinner encrypts the ticket and adds it as a cookie, but I am also able to add the encrypted ticket to cache like the original proposal. I also replaced the single UserData property with a JSON serialized object representing all of my custom properties.

CustomIdentityDTO dto = new CustomIdentityDTO { 
   UserId = userId, FirstName = firstName, LastName = lastName };
JavaScriptSerializer serializer = new JavaScriptSerializer();

FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(
  1, // version
  username,
  DateTime.Now, // creation
  DateTime.Now.AddMinutes(30), // expiration
  false, // not persistent
  serializer.Serialize(dto));

string encTicket = FormsAuthentication.Encrypt(authTicket);
//HttpContext.Current.Response.Cookies.Add(...)
HttpContext.Current.Cache.Add(username, encTicket, ...

Then I retrieve the encrypted ticket (either from cache or cookies) in global.asax through a PostAuthenticateRequest handler much like NerdDinner (for cookie) or the blogger's proposal (for cache).

NerdDinner implements IIdentity instead of IPrincipal. References to the custom fields in the code are as follows:

((CustomIdentity)Page.User.Identity).FirstName // from partial view

((CustomIdentity)User.Identity).FirstName // from controller

After working with both methods, I find that NerdDinner's approach works very well. After switching over I haven't encountered much in the way of obstacles.

What about creating an ICustomPrincipalManager interface?

public interface ICustomPrincipalManager 
{
    ICustomPrincipal Current {get;}
}

It can be implemented by a class that accesses HttpContext, the database, caching, or whatever, but you could also mock the interface for unit testing. Your controllers would use the IoC framework to get your ICustomPrincipalManager, and then access information like this:

_customPrincipalManager.Current.FirstName
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!