Frage Wo kann ich die Benutzerinformationen in die Sitzung in ASP.NET MVC 5 mit Windows-Authentifizierung laden?


Ich möchte den ASP.NET MVC 5 für meine Webanwendung verwenden. Ich brauche das windows authentication.

Wenn ich das benutze windows authentication Wo ist der beste Ort für das Lesen von Benutzerinformationen (Benutzer-ID und Rollen) und speichern Sie sie in der Session?

Ich habe die Methode, um die Benutzerinformationen nach Benutzername aus der Datenbank wie folgt zu erhalten:

public class CurrentUser
    {
        public int UserId { get; set; }

        public string UserName { get; set; }

        public Roles Roles { get; set; }
    }

    public enum Roles
    {
        Administrator,
        Editor,
        Reader
    }

    public class AuthService
    {
        public CurrentUser GetUserInfo(string userName)
        {
            var currentUser = new CurrentUser();

            //load from DB

            return currentUser;
        }
    }

5
2017-09-12 11:05


Ursprung


Antworten:


Sie haben zwei Fragen gestellt (1) den besten Ort, um Benutzerinformationen zu erhalten und (2) wie Sie ihn in der Sitzung speichern. Ich antworte (1) und zeige damit vielleicht, dass Sie keine zusätzlichen Informationen in die Sitzung einbringen müssen.

Sie haben angegeben, dass Ihre Anwendung die Windows-Authentifizierung verwendet. Dies bedeutet, dass die harte Arbeit zur Authentifizierung des Benutzers bereits von IIS / HttpListener ausgeführt wurde, bevor Ihre Anwendung die Anforderung erhält. Wenn Sie die Anfrage erhalten, wird ein WindowsPrincipal im HttpContext.User. Dadurch werden die Windows-Benutzernamen und AD-Rollen bereits eingerichtet, Sie möchten jedoch zusätzliche Rollen verwenden, die in der Datenbank gespeichert sind.

Du könntest auf deine zugreifen AuthService von überall in Ihrer Anwendung, aber wahrscheinlich ist der beste Ansatz, ein zu registrieren IAuthorizationFilter und mach die Arbeit dort. Wenn Sie diesem Ansatz folgen, sind die zusätzlichen Rollen und andere Informationen, die Sie von der Datenbank abrufen, in Ihren Controller-Methoden und, noch wichtiger, von jedem zusätzlichen Bibliothekscode verfügbar, der Benutzeranmeldeinformationen überprüfen muss.

Wenn Sie vor .Net 4.5 zusätzliche Informationen zum .Net 4.5 hinzufügen wollten WindowsPrincipal Ich denke, Ihre einzige Wahl war, den vom System zur Verfügung gestellten Benutzer durch ein anderes Objekt zu ersetzen, das den IPrincipal Schnittstelle. Dieser Ansatz ist immer noch verfügbar (und was ich empfehle), aber seit der Einführung von Windows Identity Foundation (WIF) in .Net 4.5, WindowsPrincipal ist abgeleitet von  System.Security.Claims.ClaimsIdentityClaimsIdentity, das das Hinzufügen zusätzlicher Rollen (und anderer nützlicher Informationen) zu dem vom System bereitgestellten Principal unterstützt. Wie jedoch einige Leute herausgefunden haben, gibt es in Windows einen Fehler / eine Funktion, die eine Ausnahme verursachen kann The trust relationship between the primary domain and the trusted domain failed beim Prüfen von Rollen, die programmgesteuert hinzugefügt wurden, ausgelöst werden. Wir haben festgestellt, dass ein einfacher und zuverlässiger Weg, dies zu vermeiden, darin besteht, den Benutzer durch einen zu ersetzen GenericPrincipal.

Schritte erforderlich:

(1) erstelle ein IAuthorizationFilter.

class MyAuthorizationFilter : IAuthorizationFilter
{
    AuthService _authService;

    public MyAuthorizationFilter(AuthService authService)
    {
        _authService = authService;
    }

    public void OnAuthorization(AuthorizationContext filterContext)
    {
        var principal = filterContext.HttpContext.User;

        if (principal.Identity != null && principal.Identity.IsAuthenticated)
        {
            // Add username (and other details) to session if you have a need
            filterContext.HttpContext.Session["User"] = principal.Identity.Name;

            // get user info from DB and embue the identity with additional attributes
            var user = _authService.GetUserInfo(principal.Identity.Name);

            // Create a new Principal and add the roles belonging to the user
            GenericPrincipal gp = new GenericPrincipal(principal.Identity, user.RoleNames.ToArray());
            filterContext.HttpContext.User = gp;
        }
    }
}

(2) Registrieren Sie Ihren Filter. Dies kann auf Controller-Ebene oder global registriert werden. In der Regel werden Sie dies tun App_Start\FilterConfig.cs:

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new MyAuthorizationFilter(new AuthService()));
    }
}

(3) Verwenden Sie die bereitgestellten GenericPrincipal in Ihrem Anwendungscode, um Fragen zur Benutzeridentifikation und anderen Anmeldeinformationen zu beantworten. z.B. In Ihrer Controller-Methode können Sie auf den Benutzernamen oder andere "Ansprüche" (z. B. E-Mail-Adresse) zugreifen, die in der GenericPrincipal durch deinen Filter.

        public ActionResult Index()
        {
            ViewBag.Name = HttpContext.User.Identity.Name;
            if(HttpContext.User.IsInRole("Administrator"))
            {
                // some role-specific action
            } 
            return View();
        }

Da Sie den integrierten Mechanismus zum Aufzeichnen von Principal-Rollen verwendet haben, können Sie von überall aus auf Benutzerdetails zugreifen HttpContext.User oder System.Threading.Thread.CurrentPrincipal. Auch Sie können die verwenden AuthorizeAttribute In Ihnen Controller-Methoden zu deklarieren, welche Aktionen für bestimmte Rollen oder Benutzer verfügbar sind. z.B.

   public class HomeController : Controller
    {
        [Authorize(Roles = "Administrator")]
        public ActionResult Admin()
        {
            return View();
        }

Sehen MSDN für weitere Details zu ClaimsIdentity

ich hoffe das hilft

-Rauben


3
2017-09-24 21:12



In erster Linie: niemals, noch nie, noch nie Benutzerdetails in der Sitzung speichern Ernst. Tu es einfach nicht.

Wenn Sie Windows Auth verwenden, befindet sich der Benutzer in AD. Sie haben AD, um die Benutzerinformationen zu erhalten. Microsoft hat ein MSDN-Artikel Beschreiben, wie dies gemacht werden sollte.

Die lange und kurze ist, dass Sie eine Unterklasse von erstellen UserIdentity und erweitern Sie es mit den zusätzlichen Eigenschaften, die Sie für den Benutzer zurückgeben möchten:

[DirectoryRdnPrefix("CN")]
[DirectoryObjectClass("inetOrgPerson")]
public class InetOrgPerson : UserPrincipal
{
    // Inplement the constructor using the base class constructor. 
    public InetOrgPerson(PrincipalContext context) : base(context)
    {
    }

    // Implement the constructor with initialization parameters.    
    public InetOrgPerson(PrincipalContext context, 
                         string samAccountName, 
                         string password, 
                         bool enabled)
                         : base(context, 
                                samAccountName, 
                                password, 
                                enabled)
    {
    }

    InetOrgPersonSearchFilter searchFilter;

    new public InetOrgPersonSearchFilter AdvancedSearchFilter
    {
        get
        {
            if ( null == searchFilter )
                searchFilter = new InetOrgPersonSearchFilter(this);

            return searchFilter;
        }
    }

    // Create the mobile phone property.    
    [DirectoryProperty("mobile")]
    public string MobilePhone
    {
        get
        {
            if (ExtensionGet("mobile").Length != 1)
                return null;

            return (string)ExtensionGet("mobile")[0];
        }

        set
        {
            ExtensionSet( "mobile", value );
        }
    }

    ...
}

Im obigen Beispielcode wird eine Eigenschaft hinzugefügt, die an die Benutzer des ADs gebunden wird mobile Feld. Dies geschieht durch Implementieren der Eigenschaft wie gezeigt unter Verwendung von ExtensionSetund dann kommentieren Sie die Eigenschaft mit der DirectoryProperty Attribut, um zu sagen, an welches Feld es bindet.

Das DirectoryRdnPrefix und DirectoryObjectClass Attribute für die Klasse müssen sich mit der Einrichtung Ihres ADs decken.

Sobald dies implementiert ist, werden Sie in der Lage sein, auf die Werte zuzugreifen, indem Sie einfach auf sie verweisen User.Identity. Beispielsweise, User.Identity.MobilePhone würde das zurückgeben mobile Feld von AD für den Benutzer.


1
2017-09-12 14:24