MVC3 Windows Authentication override User.Identity

Budujęintranet aplikacja używająca MVC3 z zapleczem MSSQL. Mam uwierzytelnianie i role (za pośrednictwem niestandardowego dostawcy ról) działają poprawnie. To, co próbuję teraz zrobić, to nadpisanie User.Identity, aby zezwolić na elementy takie jak User.Identity.FirstName. Ale nie mogę znaleźć żadnego kodu, który pokaże mi, jak to zrobić w WindowsIdentity

Próbowałem napisać niestandardowego dostawcę:

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; }
}

i przesłanianie uwierzytelniania WindowsA, aby zapełnić niestandardowy podmiot główny.

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

Mam punkt przerwania w funkcji uwierzytelniania, a główny jest wypełniany; jednak, gdy umieściłem punkt kontrolny w kontrolerach, użytkownik jest zwykłym RolePrincipal, zamiast mojego niestandardowego użytkownika. Co ja robię źle?

EDYTOWAĆ:

Skomentowałem powyższy kod w global.asax. Przesłoniłem atrybut AuthorizeAttribute za pomocą C #:

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;
    } 

}

I dostosowałem moją zasadę do następujących:

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();
    }
}

Teraz, kiedy umieszczam punkt przerwania, zegarek pokazuje następujące informacje o użytkowniku:

Użytkownik[CSupport.Model.CPrincipal]Tożsamość

Tożsamość jest dostępna; jednak nadal jest to, że WindowsIdentity CPrincipal jest dostępny tylko w zegarku i nie jest dostępny bezpośrednio.

EDYTOWAĆ: Dziękujemy wszystkim, którzy przyczynili się do tego. Zwiększyłeś moje zrozumienie działania różnych części.

Mam obie metody pracy, więc pomyślałem, że się podzielę.

Opcja 1: Zastąp żądanie autoryzacji w Global.asax

To jest ten, z którym idę.

Nie użyłem Application_AuthenticateRequest, ponieważ (zgodnie z tym:HttpContext.Current.User ma wartość null, mimo że uwierzytelnianie systemu Windows jest włączone) użytkownik nie został zapełniony w procesie uwierzytelniania systemu Windows, a zatem nie ma nic, czego mogę użyć, aby uzyskać informacje o użytkowniku.

Application_AuthorizeRequest jest kolejnym w łańcuchu i dzieje się po wprowadzeniu tożsamości systemu Windows.

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

To jest nadpisanie Zleceniodawcy

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);
    }
}

W ten sposób uzyskasz dostęp do zaktualizowanych informacji w nowym utworzonym głównym.

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

Opcja 2: Zastąp atrybut AuthorizeAttribute

Jest to przesłonięty główny (jest taki sam jak powyżej)

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);
    }
}

Oto nadpisanie atrybutu autoryzacji

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;
    } 

}

Tutaj możesz zmienić, który AuthorizeAttribute ma być używany i wykorzystać nowe informacje.

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

Opcja 1 obsługuje wszystko na całym świecie, opcja 2 obsługuje wszystko na poziomie indywidualnym.

questionAnswers(2)

yourAnswerToTheQuestion