Set HttpContext.Current.User from Thread.CurrentPr

2019-04-16 04:44发布

问题:

I have a security manager in my application that works for both windows and web, the process is simple, just takes the user and pwd and authenticates them against a database then sets the Thread.CurrentPrincipal with a custom principal. For windows applications this works fine, but I have problems with web applications.

After the process of authentication, when I'm trying to set the Current.User to the custom principal from Thread.CurrentPrincipal this last one contains a GenericPrincipal. Am I doing something wrong? This is my code:

Login.aspx

protected void btnAuthenticate_Click(object sender, EventArgs e)
{
    SecurityManager.Authenticate("user","pwd"); // This is where I set the custom principal in Thread.CurrentPrincipal
    FormsAuthenticationTicket authenticationTicket = new FormsAuthenticationTicket(1,
                        "user",
                        DateTime.Now,
                        DateTime.Now.AddMinutes(30),
                        false,
                        "");

    string ticket = FormsAuthentication.Encrypt(authenticationTicket);
    HttpCookie authenticationCookie = new HttpCookie(FormsAuthentication.FormsCookieName, ticket);
    Response.Cookies.Add(authenticationCookie);    
    Response.Redirect(FormsAuthentication.GetRedirectUrl("user", false));
}

Global.asax (This is where the problem appears)

protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
    HttpCookie authCookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName];
    if (authCookie == null)
        return;

    if (HttpContext.Current.User != null && HttpContext.Current.User.Identity.IsAuthenticated && HttpContext.Current.User.Identity is FormsIdentity)
    {                
        HttpContext.Current.User = System.Threading.Thread.CurrentPrincipal; //Here the value is GenericPrincipal
    }

Thanks in advance for any help.

回答1:

First of all: You need to set the principal on every request.

Forms authentication uses it's own assignment of the principal on each request. That's why you are seeing the GenericPrincipal

I usually reassign my custom prinicpal in OnPostAuthenticate when the standard authentication mechanism is done.



回答2:

JFYI, you can replace

if (HttpContext.Current.User != null && HttpContext.Current.User.Identity.IsAuthenticated && HttpContext.Current.User.Identity is FormsIdentity) { }

with

FormsIdentity formsIdentity = HttpContext.Current.User as FormsIdentity;
if (formsIdentity != null & formsIdentity.IsAuthenticated) { }

to reduce the length of if-clause



回答3:

The Intellisense tells me that HttpContext.Current.user and System.Threading.Thread.CurrentPrincipal are both of type System.Security.Principal.IPrincipal.

If I understand correctly, this means that the statement HttpContext.Current.User = System.Threading.Thread.CurrentPrincipal; will assign the value of thread principal to the httpcontext user without any casting or conversion.

I don't see where exactly in your code you are setting the value of the System.Threading.Thread.CurrentPrincipal, but I suggest you carefully examine how you set the principal. I recommend that you put breakpoints on this code and run it in the debugger. See what is happening line-by-line.



回答4:

Sorry about the VB (orrible language) however this should answer your question ...

http://www.asp.net/security/videos/use-custom-principal-objects

Then change that line of code to something like ...

HttpContext.Current.User = (CustomPrinciple)System.Threading.Thread.CurrentPrincipal;

That should give you what you need. Works perfectly for me :)



回答5:

When you use Forms Based Authentication (FBA), you get a GenericPrincipal in ASP.NET. This is normal, you are not doing anything wrong.

What where you expecting ? You could use Windows Integrated Authentication in your ASP.NET app if you were expecting a WindowsPrincipal.