簡體   English   中英

編寫可擴展的OWIN身份驗證

[英]Writing extensible OWIN authentication

我正在開發一組Web服務。 我已經基於我公司的安全性實現了自定義OWIN身份驗證,因此Authorize屬性現在可以使用了。

[Authorize]// It's working!

我想將其打包給其他人,但我想首先支持角色(或者至少對如何支持角色有一個計划/建議)。 不幸的是,我的公司沒有處理角色的標准方法,因此不同的服務(或應用程序)可能采用不同的方法。

[Authorize("Member")]// It's not working. :(

使我的身份驗證中間件易於擴展的最佳方法是什么? 我的特殊需要適合於支持角色,但是更通用的方法也可以。 我有一些想法:

  • 我可以期望他們擴展我的身份驗證。
    • 這需要開發人員進行更多維護。
    • 在使我編寫的內容可重復使用時,刪除了很大一部分價值。
  • 我可以提供相關事件。
    • 許多預建的身份驗證似乎都在執行這樣的操作。 他們在選擇中接受提供程序,並且該提供程序支持少數事件。
      • 我對這種方法不熟悉; 我不確定這是否是最佳解決方案。
      • 我當前的options對象是空的(就像許多教程一樣),我猶豫要更改它。
    • 我以前沒有寫過(也幾乎沒寫過)任何事件,所以對我個人而言這將是新的領域。

我傾向於后一種方法,但實際上我只是在黑暗中拍攝。 我非常感謝有信心確認什么最有效或最有效。

為了支持自定義屬性,例如[Authorize(“ Member”)],您可以擴展屬性並編寫自定義屬性。 擴展System.Web.Http.AuthorizeAttribute類並執行您需要做的所有檢查。

這說明了如何進行:

https://www.codeproject.com/Tips/376810/ASP-NET-WEB-API-Custom-Authorize-and-Exception-Han

這是我們解決方案中的一個實現。

public class ClaimsAuthorize : System.Web.Mvc.AuthorizeAttribute
    {
        public string PhenixPermissions { get; set; }
        public string[] NeededPermissions;

        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            Logger.Logger.Trace("ClaimsAuthorize.AuthorizeCore");

            NeededPermissions = PhenixPermissions.Split(',');

            if (!(httpContext.User.Identity is ClaimsIdentity))
            {
                return false;
            }

            var claimsIdentity = httpContext.User.Identity as ClaimsIdentity;
            Claim encodedPermissions = claimsIdentity.FindFirst(ConfigurationManager.AppSettings["ApplicationPermissionsKey"]);
            string applicationId = ClaimsHelper.GetClaimValue("audience");

            if (encodedPermissions == null)
            {
                Logger.Logger.Warn("No PhenixPermissions found. Are you logged in?");
                return false;
            }

            var tenant = AppManager.GetApplication(applicationId);

            List<string> decodedPermissions = PermissionsDecodeHelper.BitDecodePermissions(tenant.ConnectionString, encodedPermissions.Value);

            bool hasRights = false;

            foreach (var neededPermission in NeededPermissions)
            {
                if (decodedPermissions.FirstOrDefault(x => x == neededPermission) != null)
                {
                    Logger.Logger.Debug(string.Format("User '{0}' authorized to access view '{1}'.", claimsIdentity.Name.ToString(), httpContext.Request.FilePath));
                    hasRights = true;
                }
            }

            return hasRights;
        }

        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            Logger.Logger.Trace("ClaimsAuthorize.HandleUnauthorizedRequest");

            Logger.Logger.Warn(string.Format("Unauthorized to access '{0}'.", filterContext.Controller));

            filterContext.Controller.TempData["ErrorCode"] = "0123456789";
            filterContext.Controller.TempData["ErrorMessage"] = string.Format("'{0}' is not authorized to access access view '{1}'", HttpContext.Current.User.Identity.Name.ToString(), filterContext.Controller);

            filterContext.Result = new RedirectResult("~/Home/Error");
        }
    }

一些說明:PhenixPermissions是使用[ClaimsAuthorize(PhenixPermissions =“ ConsultExternalLink”)]之類的屬性時出現的字符串。

其余的是我們應用程序的一些特定邏輯,但是您應該了解它。

當允許調用Controller,API等時,只需將AuthorizeCore返回true或false即可。

希望這可以幫助

暫無
暫無

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

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