【问题标题】:Claims based authorization with ASP.NET MVC使用 ASP.NET MVC 的基于声明的授权
【发布时间】:2014-03-15 11:26:41
【问题描述】:

我阅读了很多博客文章和 stackoverflow 答案,但我仍然无法找到一个使用基于声明的身份验证和授权的真实世界开源项目,以便我了解如何实际实现这些。

到目前为止,我能找到的是 Thinktecture.IdentityModelthis blog 在示例网站上实现了基于声明的授权。如果你们能指出一些使用声明的开源项目,那将非常有帮助。

我感兴趣的是如何使用数据库检索我的应用程序的声明。

到目前为止,我尝试的是使用内存中的声明存储来模拟数据库,我已经创建了一个 CustomClaimsTransformerCustomAuthorisationManager 像这样。

public class CustomClaimsTransformer : ClaimsAuthenticationManager
    {
        public override ClaimsPrincipal Authenticate(string resourceName, ClaimsPrincipal incomingPrincipal)
        {
            //validate name claim
            string nameClaimValue = incomingPrincipal.Identity.Name;

            return CreatePrincipal(nameClaimValue);
        }

        private ClaimsPrincipal CreatePrincipal(string userName)
        {
            int userId = ClaimStore.Users.First(u => u.Value == userName).Key;
            var claims = ClaimStore.ClaimsSet.Where(c => c.Key == userId);

            var claimsCollection = claims.Select(kp => kp.Value).ToList();

            return new ClaimsPrincipal(new ClaimsIdentity(claimsCollection, "Custom"));
        }
    }

public class CustomAuthorisationManager : ClaimsAuthorizationManager
    { 
        public override bool CheckAccess(AuthorizationContext context)
        {
            string resource = context.Resource.First().Value;
            string action = context.Action.First().Value;

            if (action == "Show" && resource == "Code")
            {
                bool likesJava = context.Principal.HasClaim(ClaimStore._httpMyclaimsUsers, "True");
                return likesJava;
            }
            else if (action == "Read" && resource == "Departments")
            {
                bool readDeps = context.Principal.HasClaim(ClaimStore._httpMyclaimsDepartments, "Read");
                return readDeps;
            }
            return false;
        }
    }

如何在没有太多 IF 条件的情况下在现实场景中实现这些?

【问题讨论】:

  • 你是怎么做到的?能不能给个答案

标签: asp.net-mvc-4 authentication authorization claims-based-identity


【解决方案1】:

试试下面的链接,这似乎是一个不错的解决方案

http://developers.axiomatics.com/blog/index/entry/custom-claims-based-authorization-in-net-using-axiomatics-pep-sdk-for-net.html

你也可以定义你的策略并加载它

http://msdn.microsoft.com/en-us/library/system.security.claims.claimsauthorizationmanager.loadcustomconfiguration.aspx

如何:使用 WIF 和 ACS 在声明感知的 ASP.NET 应用程序中实现声明授权 http://msdn.microsoft.com/en-us/library/gg185907.aspx

【讨论】:

  • 感谢您提供这些宝贵的资源。我研究了每一个,Axiomatics SDK 听起来很有希望,但我不使用它。看起来我将不得不使用在 web.config 或数据库中定义的策略的自定义实现。我只是不明白如何评估规则。
  • (免责声明 - 我为 Axiomatics 工作)进行自定义实现绝不是一个好方法。有很多框架可以满足各种授权 - 从简单到复杂。微软甚至内置了基于声明的 authZ。实现自己的绝对不是要走的路
【解决方案2】:

我终于设法使用现有的 asp.net identity 2.0 表和我自己的一些表来设计具有所需功能的自己的系统。

我会将每个 AREA-CONTROLLER-ACTION 三重奏称为我系统中的资源。包括 WebAPI。区域本身就是一种资源。控制器本身就是一种资源。行动本身就是一种资源。它们的任意组合,也是一种资源。我将使用反射从系统本身自动生成所有内容。

另外,我将使用同一个AspNetRoles 表来存储我的用户组。用户属于一个或多个组(超级管理员、管理员、代理、客户端等)。

使用现有的基于角色的模型作为带有声明的基于用户组的模型,我可以让它工作。超级管理员处于上帝模式。他们可以创建较低级别的用户/组/分配权限等。

用户可以拥有特殊权限。例如,代理组中的每个人都被拒绝更新酒店,但可能也是酒店所有者的特殊代理可以被授予仅更新其酒店的特定权限。

由于整个访问控制系统在 MVC 区域控制器操作集上运行。最初没有人没有访问权限(包括超级管理员),我们逐渐定义了组/用户可以访问的部分。我们通过声明为超级管理员和管理员提供独占访问权限。默认情况下拒绝访问任何地方。

一旦我自动生成了 AREA-CONTROLLER-ACTION 集,我让用户选择哪个组可以访问哪个项目。

当用户登录时,我会获取当前用户可以访问的所有资源并将它们存储为声明。基于此,使用声明身份验证管理器,当用户请求访问某些资源时,我可以检查他们的声明并决定是否应该授予他们访问权限。

foreach(var claim in permissionClaims) {
    var parts = claim.Value.Split(new [] {
        '|'
    }, StringSplitOptions.None);
    if (parts.Length == 3) {
        //var httpMethod = parts[0];
        var action = parts[1]; 
        var api = parts[2];
        //Current.Log.Warn("Checking Access : " + req + " [action: " + action + "]");
        // is this request for a API action?
        if (api.Contains("API")) {
            // if so, req must be for a API action
            if (req.Contains("Api") && action.Contains(req)) {
                Log.Trace("User has access to API : " + req + " [action: " + action + "]");
                return true;
            }
        } else {
            // this is for a MVC action
            if (action.Contains(req)) {
                Log.Trace("User has access to MVC : " + req + " [action: " + action + "]");
                return true;
            }
        }
    }
}

我已经详细解释了该方法here - ASP.NET MVC Fine Grained Identity & Access Control

【讨论】:

  • 虽然理论上这可以回答这个问题,it would be preferable 在这里包含答案的基本部分,并提供链接以供参考。
猜你喜欢
  • 1970-01-01
  • 2012-11-07
  • 2017-06-08
  • 2021-04-13
  • 2011-08-25
  • 2018-12-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多