在哪里可以使用Windows身份验证将用户信息加载到ASP.NET MVC 5中的会话?

Jen*_*nan 5 session windows-authentication asp.net-mvc-5

我想将ASP.NET MVC 5用于我的Web应用程序.我需要使用windows authentication.

如果我使用windows authenticationwhere是读取用户信息(用户ID和角色)的最佳位置并将其存储到Session

我有从数据库中通过用户名获取用户信息的方法,如下所示:

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;
        }
    }
Run Code Online (Sandbox Code Playgroud)

Rob*_*Rob 3

您问了两个问题(1)获取用户信息的最佳位置以及(2)如何将其存储在会话中。我将回答(1),这样做也许表明您不需要在会话中添加任何附加信息。

\n\n

您已经声明您的应用程序正在使用 Windows 身份验证,因此这意味着在您的应用程序收到请求之前,IIS/HttpListener 已经完成了对用户进行身份验证的艰苦工作。当您收到请求时,将会有WindowsPrincipal一个HttpContext.User。这将已经建立 Windows 用户名和 AD 角色,但您希望使用存储在数据库中的其他角色...

\n\n

您可以从应用程序中的任何位置访问您的内容AuthService,但最好的方法可能是注册一个IAuthorizationFilter并在那里完成工作。通过采用这种方法,您从数据库获取的其他角色和其他信息将在您的控制器方法中可用,也许更重要的是,从需要检查用户凭据的任何其他库代码中可用。

\n\n

在.Net 4.5之前,如果你想添加额外的信息,WindowsPrincipal我认为你唯一的选择就是用另一个实现该接口的对象替换系统提供的 User IPrincipal。此方法仍然可用(也是我推荐的方法),但由于 .Net 4.5 中引入的 Windows Identity Foundation (WIF)WindowsPrincipal源自\xe2\x80\x82System.Security.Claims.ClaimsIdentityClaimsIdentity,它支持向系统提供的主体添加其他角色(和其他有用信息)。然而,正如一些人发现的那样,Windows 中存在一个错误/功能,可能会导致The trust relationship between the primary domain and the trusted domain failed在检查以编程方式添加的角色时引发异常。我们发现避免这种情况的一个简单可靠的方法是将 User 替换为GenericPrincipal.

\n\n

所需步骤:

\n\n

(1) 创建一个IAuthorizationFilter.

\n\n
class MyAuthorizationFilter : IAuthorizationFilter\n{\n    AuthService _authService;\n\n    public MyAuthorizationFilter(AuthService authService)\n    {\n        _authService = authService;\n    }\n\n    public void OnAuthorization(AuthorizationContext filterContext)\n    {\n        var principal = filterContext.HttpContext.User;\n\n        if (principal.Identity != null && principal.Identity.IsAuthenticated)\n        {\n            // Add username (and other details) to session if you have a need\n            filterContext.HttpContext.Session["User"] = principal.Identity.Name;\n\n            // get user info from DB and embue the identity with additional attributes\n            var user = _authService.GetUserInfo(principal.Identity.Name);\n\n            // Create a new Principal and add the roles belonging to the user\n            GenericPrincipal gp = new GenericPrincipal(principal.Identity, user.RoleNames.ToArray());\n            filterContext.HttpContext.User = gp;\n        }\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

(2) 注册您的过滤器。这可以在控制器级别或全局注册。通常您将在以下位置执行此操作App_Start\\FilterConfig.cs

\n\n
public class FilterConfig\n{\n    public static void RegisterGlobalFilters(GlobalFilterCollection filters)\n    {\n        filters.Add(new MyAuthorizationFilter(new AuthService()));\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

(3) 使用GenericPrincipal您的申请代码中提供的信息来回答有关用户身份和其他凭据的问题。GenericPrincipal例如,在您的控制器方法中,您可以访问过滤器中存储的用户名或任何其他“声明”(例如电子邮件地址) 。

\n\n
        public ActionResult Index()\n        {\n            ViewBag.Name = HttpContext.User.Identity.Name;\n            if(HttpContext.User.IsInRole("Administrator"))\n            {\n                // some role-specific action\n            } \n            return View();\n        }\n
Run Code Online (Sandbox Code Playgroud)\n\n

由于您已使用内置机制来记录主体角色,因此您可以使用HttpContext.User或从任何地方访问用户详细信息System.Threading.Thread.CurrentPrincipal。您还可以使用AuthorizeAttribute控制器中的方法来声明哪些操作可供某些角色或用户使用。例如

\n\n
   public class HomeController : Controller\n    {\n        [Authorize(Roles = "Administrator")]\n        public ActionResult Admin()\n        {\n            return View();\n        }\n
Run Code Online (Sandbox Code Playgroud)\n\n

有关 ClaimsIdentity 的更多详细信息,请参阅MSDN

\n\n

我希望这有帮助

\n\n

-抢

\n