ASP.NET MVC Creating a Personalized User

I have an MVC application where I have a User class, and the user can also impersonate another user (Admin users only).

So, I have this code below that authenticates the request and instantiates my version of the User class.

He then tries to get the impersonated user from the Session object, but Session is not available in this method in global.asax.

Hope this makes sense.

How else can I do this?

My question is, I think, at what point in the global.asax methods do you access the Session object for each request?

protected void Application_OnAuthenticateRequest(object sender, EventArgs e) { IMylesterService service = ObjectFactory.GetInstance<IMylesterService>(); if (Context.User != null) { if (Context.User.Identity.IsAuthenticated) { User user = service.GetUser(Context.User.Identity.Name); if (user == null) throw new ApplicationException("Context.user.Identity.name is not a recognized user"); User impersonatedUser = (User)this.Session["ImpersonatedUser"]; if (impersonatedUser == null) user.ImpersonatedUser = user; else user.ImpersonatedUser = impersonatedUser; System.Threading.Thread.CurrentPrincipal = Context.User = user; return; } } User guest = service.GetGuestUser(); guest.ImpersonatedUser = guest; System.Threading.Thread.CurrentPrincipal = Context.User = guest; } 
+4
source share
3 answers

Try creating an authorization filter:

 public class CustomAuthorizationFilter : AuthorizeAttribute { protected override bool AuthorizeCore(System.Web.HttpContextBase httpContext) { // perform your authorization here // full access to HttpContext and session } } 

You can then apply this attribute to your controllers. Ideally, you will have a base controller, to which all other controllers are inherited, and you can apply the attribute at the class level on this controller. Then all your requests will be resolved and will apply impersonation, as you indicated above.

+1
source

The session will not be available during AuthenticateRequest: you will need to mark the required information in Identity.userData; for example, if you use forms authentication, follow these steps:

 void Application_AuthenticateRequest(object sender, EventArgs e) { if (Context.User != null) { if (Context.User.Identity.IsAuthenticated) { // retrieve the value var id = (FormsIdentity)Context.User.Identity; var myvalue = id.Ticket.UserData; // "Here you are" } } } 

To enter forms using forms, you need to write a custom cookie: MVC -> FormsAuthenticationService class: IFormsAuthenticationService

 public static void SetAuthenticationCookie(HttpContextBase context, FormsAuthenticationTicket ticket) { var cookie = new HttpCookie(FormsAuthentication.FormsCookieName) { Value = FormsAuthentication.Encrypt(ticket), Secure = FormsAuthentication.RequireSSL, Domain = FormsAuthentication.CookieDomain, HttpOnly = true, Expires = DateTime.Now.AddMinutes(15) }; if (!context.Request.IsSecureConnection && FormsAuthentication.RequireSSL) { throw new HttpException("Ticket requires SSL."); } context.Response.Cookies.Add(cookie); } public static FormsAuthenticationTicket CreateTicket(HttpContextBase context, string emailAddress, string userData, bool persist) { return new FormsAuthenticationTicket(1, emailAddress, DateTime.Now, DateTime.Now.AddMinutes(15), persist, userData, FormsAuthentication.FormsCookiePath); } 

Finally, in SignIn, you will create the required ticket by calling CreateTicket (...), and then you will write it SetAuthenticationCookie (...).

 public void SignIn(string userName, string password) { if(CheckUserValid(userName,password, out string email)) { var ticket = CreateTicket(email, "Here you are", true); SetAuthenticationCookie(HttpContext.Current.Base(), ticket); } } 

I have never used it, but I assume that session state is assigned during AcquireRequestState:

 public void Init(HttpApplication context) { context.AcquireRequestState += new EventHandler(context_AcquireRequestState); } 
0
source

I had the same problem related to the need to access the session in global.asax and finally solved it by moving my code to the AcquireRequestState handler, which occurs after authentication.

  protected void Application_AcquireRequestState(Object sender, EventArgs e) { if (Request.IsAuthenticated && Context.Session != null) { // access Context.Session } } 

This works very hard, and the current context does not always have a valid session object, so check.

EDIT : had to add a check for IsAuthenticated too - received a zero error when exiting the system. It works great.

0
source

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


All Articles