从 Active Directory 进行身份验证,但在 MVC 中从 SQL 数据库中授权角色

Sav*_*ngh 6 c# model-view-controller asp.net-mvc windows-authentication

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

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

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

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

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

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

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

我在以下位置找到了此解决方案:此站点但它用于 AD 组。

Sav*_*ngh 2

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