本文介绍了ASP.NET安全:角色名的单一入口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正在构建一个ASP.NET应用程序,并且必须使用企业LDAP系统(SiteMinder的)进行身份验证的要求(上行:没有登录对话框)。角色是在LDAP工具创建的,并且用户被分配到由用户级经理人的角色(读:该结构具有易于理解)。目前,使用该系统的所有应用程序使用一个双输入过程,从而在应用程序中确定的角色是手工输入到LDAP系统和用户分配,然后应用功能分配给他们的角色镜子应用程序为基础的控制面板。这工作,但它困扰我,双项是必需的。

We're building an ASP.NET app, and have a requirement to use the corporate LDAP system (Siteminder) for authentication (upside: no login dialogs). Roles are created in the LDAP tool, and users are assigned to the roles by userland managers (read: the structure has to be easily understood). Currently, all apps that use the system use a dual-entry process whereby the roles identified in the app are hand-entered into the LDAP system and users are assigned, then app functions are assigned to their role mirrors in an app-based control panel. This works, but it bothers me that dual-entry is required.

我想实现的东西,其中应用程序查询LDAP系统,以获得分配给应用程序(这是在LDAP系统标识)的角色列表和填充作用:与他们功能的控制面板。这部分似乎真的简单。不过,我失去了清晰度,当谈到搞清楚放什么在授权属性:

What I would like to achieve is something where the app queries the LDAP system to get a list of roles that are assigned to the app (which is identified in the LDAP system) and populate the role:function control panel with them. This part seems really straightforward. However, I lose clarity when it comes to figuring out what to put in the Authorize attribute:

[Authorize(Roles = "Admin, Moderator")]

将成为...什么?

would become... what?

[Authorize(LoadedRoles(r => r.FindAll("some expression that describes the roles that have a particular permission")))]

我是认真到蓝天的领土这里。我读和喜欢 - 从架构的角度来看 - 的答案建议制定权限的角色。但是,这可能不会接受,如果需要管理用户的用户级经理人。在另一方面,变成的东西变成非字符串资源,但我无法想象如何翻译成有这样的功能,包括角色。

I'm seriously into blue sky territory here. I read this question, and liked - from an architectural standpoint - the answer that suggested making the permissions the roles. But that might not be acceptable to the userland managers that needed to manage users. On the other hand, this question turns things into non-string resources, but I can't conceive of how to translate that into "roles that have this sort of function included".

有什么建议?

更新:

,我已经取得了一些进展。从目前来看,我在封装一切 [AuthorizeFunctionAttribute] ,并将农场的各个部分在哪里他们后来的归属。为此,我创建了三个变量:

Based on the advice of @venerik below, I've made some progress. For the time being, I'm encapsulating everything in the [AuthorizeFunctionAttribute], and will farm the individual pieces out where they belong later. To that end, I created three variables:

    private IList<KeyValuePair<long, string>> Roles;
    private IList<KeyValuePair<long, string>> Functions;
    private IList<RoleFunction> RoleFunctions;

......然后把静态数据在其中:

...then put static data in them:

Roles = new ICollection<KeyValuePair<long, string>>();
Roles.Add(KeyValuePair<long, string>(1, "Basic User"));
Roles.Add(KeyValuePair<long, string>(2, "Administrator"));

Functions = new ICollection<KeyValuePair<long, string>>();
Functions.Add(KeyValuePair<long,string>(1,"List Things"));
Functions.Add(KeyValuePair<long,string>(2,"Add Or Edit Things"));
Functions.Add(KeyValuePair<long,string>(3,"Delete Things"));

...并最终结合在一起(以复杂的方式奠定了基础的未来):

...and finally bound them together (in a complicated manner that lays the groundwork for the future):

RoleFunctions = new IList<RoleFunction>();
RoleFunctions.Add(
   new RoleFunction
   {
      RoleId = Roles.Where( r => r.Value == "Basic User").FirstOrDefault().Key,
      FunctionId = Functions.Where( f => f.Value == "List Things" ).FirstOrDefault().Key,
      isAuthorized = true
   },
   new RoleFunction
   {
      RoleId = Roles.Where( r => r.Value == "Administrator").FirstOrDefault().Key,
      FunctionId = Functions.Where( f => f.Value == "Add or Edit Things" ).FirstOrDefault().Key,
      isAuthorized = true
   },
   // More binding...
);

我感觉很好,这个至今。于是我就去研究看什么我需要在那里做。然而,每个页面底部的评论,这不是非常有帮助。我或多或少得到月末,该方法需要返回一个布尔值。而我得到的,我需要检查 User.Roles 阵列选择一个适合则传递通过许可[AuthorizeFunction(列出的东西) ]

I feel good about this so far. So I went researching AuthorizeCore to see what I needed to do there. However, per the comment at the bottom of the page, it's not very helpful. I more or less get that at the end, the method needs to return a bool value. And I get that I need to check that one of the User.Roles array fits the permission that's passed in through [AuthorizeFunction("List Things")].

更新(再次):

我有以下code,这似乎是它会做什么,我需要(一个方法需要充实):

I've got the following code, which seems like it will do what I need (one method needs fleshing out):

/// <summary>An authorization attribute that takes "function name" as a parameter
/// and checks to see if the logged-in user is authorized to use that function.
/// </summary>
public class AuthorizeFunctionAttribute : AuthorizeAttribute
{
    private IList<KeyValuePair<long, string>> Roles;
    private IList<KeyValuePair<long, string>> Functions;
    private IList<RoleFunction> RoleFunctions;

    public string Function { get; private set; }

    public AuthorizeFunctionAttribute(string FunctionName)
    {
        Function = FunctionName;
        Roles = SetApplicationRoles();
        Functions = SetApplicationFunctions();
        RoleFunctions = SetRoleFunctions();
    }

    protected virtual bool AuthorizeCore(HttpContextBase httpContext)
    {
        bool userIsAuthorized = false;
        foreach (string ur in GetUserRoles(httpContext.Current.Request.Headers["SM_USER"]))
        {
            long roleId = Roles.Where( sr => sr.Value == ur )
                .First().Key;
            long functionId = Functions.Where( sf => sf.Value == Function )
                .First().Key;
            // If any role is authorized for this function, set userIsAuthorized to true.
            // DO NOT set userIsAuthorized to false within this loop.
            if (RoleFunctions.Where(rf => rf.RoleId == roleId && rf.FunctionId == functionId)
                .First().isAuthorized)
            {
                userIsAuthorized = true;
            }
        }
        return userIsAuthorized;
    }

previously我不知道有足够的了解创建自定义属性,走出自己的路的基本位。但是,告诉我应该是明显,我在开始的时候:建立它自己。所以,一旦我得到的 GetUserRoles将()方法放在一起,我应该是正在进行中。

Previously I didn't know enough about the underlying bits of creating a custom attribute to get out of my own way. However, this MSDN article told me what should have been obvious to me in the beginning: build it yourself. So, once I get the GetUserRoles() method put together, I should be underway.

推荐答案

我觉得你可以这样使用自定义解决 AuthorizeAttribute 。在一个项目中,我努力接近他们使用的访问Active Directory(如this回答)。

I think you can solve this using a custom AuthorizeAttribute. In a project I worked close to they used that to access Active Directory (as described in this answer).

在你的情况下,它看起来是这样的:

In your case it would look something like:

public class AuthorizeWithLDAPAttribute(string functionName) : AuthorizeAttribute
{
    protected virtual bool AuthorizeCore(HttpContextBase httpContext)
    {
         // check LDAP to verify that user has
         // a role that's linked to `functionName`
    }
}

接下来,您可以在您的控制器和/或方法使用该属性:

Next you can use this attribute on your controllers and/or methods:

[AuthorizeWithLDAP("functionName1")]
public class BlogController : Controller
{
    ....
    [AuthorizeWithLDAP("functionName2")]
    public ViewResult Index()
    {
         return View();
    }
}

该控制器现在只给其角色被链接到 functionName1 和方法只是给其角色被链接到 functionName1访问访问 functionName2

The controller is now only accessible to users whose role are linked to functionName1 and the method is only accessible to users whose role are linked to functionName1 and functionName2

这篇关于ASP.NET安全:角色名的单一入口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-24 18:01