使用Windows身份验证,在哪里可以将用户信息加载到ASP.NET MVC 5中的会话中? [英] Where can I load the user information to the session in ASP.NET MVC 5 with windows authentication?

查看:85
本文介绍了使用Windows身份验证,在哪里可以将用户信息加载到ASP.NET MVC 5中的会话中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to use the ASP.NET MVC 5 for my web app. I need use the windows authentication.

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

If I use the windows authentication where is the best place for reading user information (userid and roles) and store its to the Session?

我有这样一种通过用户名从数据库中获取用户信息的方法:

I have the method for getting the user information by username from the database like this:

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

推荐答案

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

You've asked two questions (1) the best place to obtain user information and (2) how to store it in the Session. I'll answer (1) and in so doing perhaps show that you need not put any additional information in the session.

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

You've stated that your application is using Windows Authentication, so that means the hard work of authenticating the user has already been done by IIS/HttpListener before your app receives the request. When you receive the request there will be a WindowsPrincipal in HttpContext.User. This will have the windows username and AD roles already established, but you wish to use additional roles stored in the database...

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

You could access your AuthService from anywhere in your application, but probably the best approach is to register an IAuthorizationFilter and do the work there. By following this approach, the additional roles and other information you fetch from the database will be available in your controller methods and, perhaps more importantly, from any additional library code that needs to check user credentials.

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

Prior to .Net 4.5, if you wanted to add additional information to the WindowsPrincipal I think your only choice was to replace the system-provided User with another object that implemented the IPrincipal interface. This approach is still available (and what I recommend), but since the introduction of Windows Identity Foundation (WIF) in .Net 4.5, WindowsPrincipal is derived from  System.Security.Claims.ClaimsIdentityClaimsIdentity, which supports adding additional roles (and other useful information) to the system-provided principal. However, as several people have found, there is a bug/feature in Windows which can cause an exception The trust relationship between the primary domain and the trusted domain failed to be thrown when checking roles that have been added programmatically. We have found that a simple and reliable way to avoid this is to replace the User with a GenericPrincipal.

所需步骤:

(1)创建一个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)注册您的过滤器.可以在控制器级别或全局注册.通常,您将在App_Start\FilterConfig.cs中完成此操作:

(2) Register your filter. This can be registered at the controller level or globally. Typically you will do this in App_Start\FilterConfig.cs:

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

(3)在应用程序代码中使用提供的GenericPrincipal来回答有关用户标识和其他凭据的问题.例如在控制器方法中,您可以通过过滤器访问存储在GenericPrincipal中的用户名或任何其他声明"(例如电子邮件地址).

(3) Use the provided GenericPrincipal in your application code to answer questions about the user identification and other credentials. e.g. in your controller method you can access the username or any other "claims" (e.g. email address) stored in the GenericPrincipal by your filter.

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

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

Because you've used the built-in mechanism to record Principal roles, you can access user details from anywhere using HttpContext.User or System.Threading.Thread.CurrentPrincipal. Also you can use the AuthorizeAttribute in you controller methods to declare which actions are available to certain roles or users. e.g.

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

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

See MSDN for further details about ClaimsIdentity

我希望这对您有帮助

-Rob

这篇关于使用Windows身份验证,在哪里可以将用户信息加载到ASP.NET MVC 5中的会话中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆