繁体   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