MVC3-Windows-Authentifizierung überschreibt User.Identity

Ich baue einIntranet Anwendung mit MVC3 mit einem MSSQL-Backend. Ich habe Authentifizierung und Rollen (über einen benutzerdefinierten Rollenanbieter), die ordnungsgemäß funktionieren. Ich versuche jetzt, User.Identity zu überschreiben, um Elemente wie User.Identity.FirstName zuzulassen. Ich kann jedoch keinen Code finden, der mir zeigt, wie dies in WindowsIdentity funktioniert

Ich habe versucht, einen benutzerdefinierten Anbieter zu schreiben:

public class CPrincipal : WindowsPrincipal
{
    UserDAL userDAL = new UserDAL();
    public CPrincipal(WindowsIdentity identity)
        : base(identity)
    {
        userInfo = userDAL.GetUserProfile(identity.Name.Split('\\')[1]);
        this.identity = identity;
    }
    public UserInfo userInfo { get; private set; }
    public WindowsIdentity identity { get; private set; }
}

und Überschreiben der WindowsAuthentication, um das benutzerdefinierte Prinzipal aufzufüllen.

    void WindowsAuthentication_OnAuthenticate(object sender, WindowsAuthenticationEventArgs e)
    {
        if (e.Identity != null && e.Identity.IsAuthenticated)
        {
            CPrincipal cPrincipal = new CPrincipal(e.Identity);
            HttpContext.Current.User = cPrincipal;
        }
    }

Ich habe einen Haltepunkt in der Authentifizierungsfunktion und der Principal wird aufgefüllt. Wenn ich jedoch einen Haltepunkt in den Controllern platziere, ist der Benutzer nur der normale RolePrincipal anstelle meines benutzerdefinierten Principals. Was mache ich falsch?

BEARBEITEN:

Ich habe den obigen Code in der global.asax auskommentiert. Ich habe das AuthorizeAttribute mit C # überschrieben:

public class CAuthorize : AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        bool authorized = base.AuthorizeCore(httpContext);
        if (!authorized)
        {
            return false;
        }


        IIdentity user = httpContext.User.Identity;
        CPrincipal cPrincipal = new CPrincipal(user);
        httpContext.User = cPrincipal;

        return true;
    } 

}

Und passte mein Prinzipal an das Folgende an:

public class CPrincipal : IPrincipal
{
    private UserDAL userDAL = new UserDAL();
    public CPrincipal(IIdentity identity)
    {
        userInfo = userDAL.GetUserProfile(identity.Name.Split('\\')[1]);
        this.Identity = identity;
    }
    public UserInfo userInfo { get; private set; }

    public IIdentity Identity { get; private set; }

    public bool IsInRole(string role)
    {
        throw new NotImplementedException();
    }
}

Wenn ich jetzt einen Haltepunkt einfüge, zeigt die Uhr im Benutzer Folgendes:

Nutzer[CSupport.Model.CPrincipal]Identität

Identität ist zugänglich; es ist jedoch immer noch der WindowsIdentity-CPrincipal, auf den nur in der Uhr und nicht direkt zugegriffen werden kann.

BEARBEITEN: Vielen Dank an alle, die dazu beigetragen haben. Sie haben mein Verständnis der Funktionsweise der verschiedenen Teile erheblich erweitert.

Ich habe beide Wege zur Arbeit, also dachte ich, ich würde teilen.

Option 1: Überschreiben Sie die Autorisierungsanforderung in Global.asax

Dies ist die, mit der ich gehe.

Ich habe Application_AuthenticateRequest nicht verwendet, weil (demnach:HttpContext.Current.User ist null, obwohl die Windows-Authentifizierung aktiviert ist) Der Benutzer wurde nicht in einen Windows-Authentifizierungsprozess eingebunden, und daher kann ich nichts verwenden, um die Benutzerinformationen abzurufen.

Application_AuthorizeRequest ist der nächste in der Kette und wird ausgeführt, nachdem die Windows-Identität eingegeben wurde.

    protected void Application_AuthorizeRequest(object sender, EventArgs e)
    {
        if (User.Identity.IsAuthenticated && Roles.Enabled)
        {
            Context.User = new FBPrincipal(HttpContext.Current.User.Identity);
        }
    }

Dies ist die Außerkraftsetzung des Auftraggebers

public class CPrincipal : IPrincipal
{
    private UserDAL userDAL = new UserDAL();
    public CPrincipal(IIdentity identity)
    {
        userInfo = userDAL.GetUserProfile(identity.Name.Split('\\')[1]);
        this.Identity = identity;
    }
    public UserInfo userInfo { get; private set; }

    public IIdentity Identity { get; private set; }

    public bool IsInRole(string role)
    {
        return userDAL.IsUserInRole(userInfo.UserName, role);
    }
}

Auf diese Weise greifen Sie auf die aktualisierten Informationen in dem neu erstellten Principal zu.

    [Authorize(Roles = "super admin")]
    public ActionResult Dashboard()
    {
        string firstname = (User as CPrincipal).userInfo.FirstName; // <--
        DashboardModel dModel = reportDAL.GetChartData();
        return View(dModel);
    }

Option 2: Überschreiben Sie das AuthorizeAttribute

Dies ist das überschriebene Prinzipal (es ist dasselbe wie oben)

public class CPrincipal : IPrincipal
{
    private UserDAL userDAL = new UserDAL();
    public CPrincipal(IIdentity identity)
    {
        userInfo = userDAL.GetUserProfile(identity.Name.Split('\\')[1]);
        this.Identity = identity;
    }
    public UserInfo userInfo { get; private set; }

    public IIdentity Identity { get; private set; }

    public bool IsInRole(string role)
    {
        return userDAL.IsUserInRole(userInfo.UserName, role);
    }
}

Hier ist die Außerkraftsetzung des Berechtigungsattributs

public class CAuthorize : AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        bool authorized = base.AuthorizeCore(httpContext);
        if (!authorized)
        {
            return false;
        }


        IIdentity user = httpContext.User.Identity;
        CPrincipal cPrincipal = new CPrincipal(user);
        httpContext.User = cPrincipal;

        return true;
    } 

}

Hier können Sie das zu verwendende AuthorizeAttribute ändern und die neuen Informationen verwenden.

    [CAuthorize(Roles = "super admin")] // <--
    public ActionResult Dashboard()
    {
        string firstname = (User as CPrincipal).userInfo.FirstName; // <--
        DashboardModel dModel = reportDAL.GetChartData();
        return View(dModel);
    }

Option 1 behandelt alles global, Option 2 behandelt alles auf individueller Ebene.

Antworten auf die Frage(2)

Ihre Antwort auf die Frage