首页 > 解决方案 > 从 Active Directory 进行身份验证,但从 MVC 中的 SQL 数据库授权角色

问题描述

我是 MVC 的新手。我搜索并没有找到适合我要求的解决方案。

我正在为我们团队的内部使用开发一个门户网站,它使用 Windows AD 身份验证进行登录。但是,对于基于角色的访问,我创建了一个本地数据库,它可以返回用户的角色详细信息。我创建了一个自定义授权过滤器,允许我根据用户的角色处理授权。此过滤器正在从数据库中查询详细信息,但是这种方法的问题是,它将尝试从数据库中获取对控制器的每个请求的详细信息,这使得它变得昂贵。

如何将从数据库中获取的用户详细信息保存在令牌中,这样我就不必为每个请求查询数据库并在授权过滤器中使用令牌值。此外,我可以在应用程序的其他任何地方使用从数据库中为用户检索的值。(我们在数据库中拥有的用户还有一些其他详细信息)。

如果有人可以提出更好的方法来实现这一点,请提供帮助。

这是我目前在授权过滤器中使用的代码:

public class AuthorizeRole : AuthorizeAttribute
{
    private bool _authenticated;
    private bool _authorized;

    public string InRoles { get; set; }

    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        base.HandleUnauthorizedRequest(filterContext);

        if (_authenticated && !_authorized)
        {
            filterContext.Result = new RedirectResult("/account/error");
        }
    }

    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        _authenticated = base.AuthorizeCore(httpContext);

        if (_authenticated)
        {
            if (string.IsNullOrEmpty(InRoles))
            {
                _authorized = true;
                return _authorized;
            }

            if (!string.IsNullOrEmpty(httpContext.User.Identity.Name))
            {
                string NTID = httpContext.User.Identity.Name.Split('\\')[1];
                var roles = InRoles.Split(',');

                using (Models.UserAuthEntities userAuthEntities = new Models.UserAuthEntities())
                {
                    try
                    {
                        ObjectResult<Models.Validate_User_Login_Result> userResults = userAuthEntities.Validate_User_Login(NTID);
                        var user = userResults.FirstOrDefault(all => all.NTID == NTID);

                        if (user == null)
                        {
                            _authorized = false;
                            return _authorized;
                        }
                        else
                        {
                            if (roles.Contains(user.Role))
                            {
                                return _authorized;
                            }
                        }
                    }
                    catch (Exception)
                    {
                        _authorized = false;
                        return _authorized;
                    }
                }
            }
            else
            {
                _authorized = false;
                return _authorized;
            }
        }

        _authorized = false;
        return _authorized;
    }
}

请建议在哪个部分使用您将建议的代码(例如,在控制器内部、在过滤器内部或其他地方。)

我在以下位置找到了这个解决方案:this site but there is used for AD groups。

标签: c#asp.net-mvcmodel-view-controllerwindows-authentication

解决方案


我已经在AuthorizeCore它现在工作的方法的覆盖版本中检查了 cookie:

    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        string cookieName = FormsAuthentication.FormsCookieName;
        HttpCookie authCookie = httpContext.Request.Cookies[cookieName];
        _authenticated = base.AuthorizeCore(httpContext);
        string authToken = httpContext.Request.Headers["Auth-Token"];

        if (_authenticated)
        {
            if (authCookie == null)
            {
                if (string.IsNullOrEmpty(InRoles))
                {
                    _authorized = true;
                    return _authorized;
                }

                if (!string.IsNullOrEmpty(httpContext.User.Identity.Name))
                {
                    string NTID = httpContext.User.Identity.Name.Split('\\')[1];
                    var roles = InRoles.Split(',');

                    using (Models.UserAuthEntities userAuthEntities = new Models.UserAuthEntities())
                    {
                        try
                        {
                            ObjectResult<Models.Validate_User_Login_Result> userResults = userAuthEntities.Validate_User_Login(NTID);
                            var user = userResults.FirstOrDefault(all => all.NTID == NTID);

                            if (user == null)
                            {
                                _authorized = false;
                                return _authorized;
                            }
                            else
                            {
                                if (roles.Contains(user.Role))
                                {
                                    _authorized = true;
                                    return _authorized;
                                }
                            }
                        }
                        catch (Exception)
                        {
                            _authorized = false;
                            return _authorized;
                        }
                    }
                }
                else
                {
                    _authorized = false;
                    return _authorized;
                }
            }
        }

        _authorized = false;
        return _authorized;
    }

推荐阅读