簡體   English   中英

從Active Directory進行身份驗證,但在MVC中從SQL數據庫授權角色

[英]Authenticate from Active Directory but Authorize Roles from SQL Database in MVC

我是MVC的新手。 我搜索並找不到符合我要求的解決方案。

我正在為我們團隊的內部使用開發一個Web門戶,它使用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;
    }
}

請建議在哪個部分使用您建議的代碼(例如,內部控制器,內部過濾器或其他地方。)

我在以下網站找到了這個解決方案,但它用於AD組。

首先,您可能希望使用AD安全組來管理訪問。 這樣,OPS可以繼續在熟悉的經過時間考驗的平台上維護訪問,而您不必編寫自己的安全定義界面。

至於MVC安全持久性你要做的就是添加一個手動登錄來執行上面的邏輯,然后你使用內置的Membership Provider(對於你正在使用的任何版本的MVC)來記錄用戶.MVC將處理維護登錄狀態並為您進行標記,您可以在web.config(或Core中的settings.json)中指定諸如超時之類的內容。

對不起,我手邊沒有任何示例代碼可供說明。

我已經在方法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;
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM