Custom Principle in ASP.NET MVC

I want to have access to user properties for an authenticated user, such as UserId and FirstName, without querying the database each time. I found this site through a post on Stack Overflow, and I like this approach, but I use IoC / repositories and decided not to try to get global .asax to communicate with the database, fearing that it will not be compatible with the repository template.

Instead, I created an interface for CustomPrincipal, and I use IoC (Castle) to instantiate and pass it to the controllers (and then to the base controller).

The base controller uses the methods I created in CustomPrincipal to accomplish the same task as the blog author in global.asax. Namely, CustomPrincipal is initialized from a database or cache and assigned to HttpContext.Current.User.

My controllers / views can then reference the properties as follows:

((ICustomPrincipal)(HttpContext.Current.User)).FirstName;

This works, but I feel some smells of code. First of all, if I refer to the HttpContext from the controllers, I killed unit testing. I'm thinking of modifying my CustomPrincipal object to return the above value (such that I can mock it in my unit tests), but I'm wondering if this is a workaround, not a good solution.

Am I going to do it right? Are there any small tricks that I can do to make this a reliable solution, or should I start from scratch using a FormsAuthenticationTicket or something like that?

Thank!

+3
source share
2 answers

I wanted to throw away an alternative idea so that people looking for this information could choose.

I went looking for a viable example of FormsAuthenticationTicket and found that NerdDinner was doing a pretty decent job, adding custom properties without affecting unit testing.

LogOn ( ) FormsAuthenticationTicket. NerdDinner cookie, , . UserData JSON, .

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, ...

( cookie) global.asax PostAuthenticateRequest, NerdDinner ( cookie) ( ).

NerdDinner IIdentity IPrincipal. :

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

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

, NerdDinner . .

+7

ICustomPrincipalManager?

public interface ICustomPrincipalManager 
{
    ICustomPrincipal Current {get;}
}

, HttpContext, , .., . IoC ICustomPrincipalManager, :

_customPrincipalManager.Current.FirstName
+2

Source: https://habr.com/ru/post/1765865/


All Articles