.NET中的身份验证,授权,用户和角色管理以及一般安全性

时间:2009-08-03 15:29:20

标签: c# security authorization roles

我需要知道如何为C#应用程序实现一般安全性。在这方面我有什么选择?如果满足我的需求,我宁愿使用现有的框架 - 我不想重新发明轮子。

我的要求如下:

  • 通常的用户名/密码身份验证
  • 管理用户 - 为用户分配权限
  • 管理角色 - 将用户分配给角色,为角色分配权限
  • 基于用户名和角色的用户授权

我正在寻找一个由.Net社区进行时间处理和使用的免费/开源框架/库。

我的应用程序采用客户端/服务器方法,服务器作为Windows服务运行,连接到SQL Server数据库。客户端和服务器之间的通信将通过WCF进行。

另一件重要的事情是,我需要能够为查看/更新/删除特定实体分配特定用户或角色权限,无论是客户还是产品等。杰克可以查看10个客户中的3个,但只更新微软,雅虎和谷歌客户的详细信息,并且只能删除雅虎。

7 个答案:

答案 0 :(得分:33)

对于粗粒度安全性,您可能会发现内置的主体代码很有用;用户对象(及其角色)由“主体”在.NET中控制,但有用的是运行时本身可以强制执行此操作。

主体的实现可以是实现定义的,你通常可以自己注入; for example in WCF

要查看运行时强制执行粗略访问(即可以访问哪些功能,但不限于哪些数据):

static class Roles {
    public const string Administrator = "ADMIN";
}
static class Program {
    static void Main() {
        Thread.CurrentPrincipal = new GenericPrincipal(
            new GenericIdentity("Fred"), new string[] { Roles.Administrator });
        DeleteDatabase(); // fine
        Thread.CurrentPrincipal = new GenericPrincipal(
            new GenericIdentity("Barney"), new string[] { });
        DeleteDatabase(); // boom
    }

    [PrincipalPermission(SecurityAction.Demand, Role = Roles.Administrator)]
    public static void DeleteDatabase()
    {
        Console.WriteLine(
            Thread.CurrentPrincipal.Identity.Name + " has deleted the database...");
    }
}

但是,这对细粒度访问没有帮助(即“Fred可以访问客户A而不是客户B”)。


附加;当然,对于细粒度,您可以通过检查主体上的IsInRole来简单地在运行时检查所需的角色:

static void EnforceRole(string role)
{
    if (string.IsNullOrEmpty(role)) { return; } // assume anon OK
    IPrincipal principal = Thread.CurrentPrincipal;
    if (principal == null || !principal.IsInRole(role))
    {
        throw new SecurityException("Access denied to role: " + role);
    }
}
public static User GetUser(string id)
{
    User user = Repository.GetUser(id);
    EnforceRole(user.AccessRole);
    return user;
}

您也可以编写自己的主体/身份对象,对角色进行延迟测试/缓存,而不是必须事先了解它们:

class CustomPrincipal : IPrincipal, IIdentity
{
    private string cn;
    public CustomPrincipal(string cn)
    {
        if (string.IsNullOrEmpty(cn)) throw new ArgumentNullException("cn");
        this.cn = cn;
    }
    // perhaps not ideal, but serves as an example
    readonly Dictionary<string, bool> roleCache =
        new Dictionary<string, bool>();
    public override string ToString() { return cn; }
    bool IIdentity.IsAuthenticated { get { return true; } }
    string IIdentity.AuthenticationType { get { return "iris scan"; } }
    string IIdentity.Name { get { return cn; } }
    IIdentity IPrincipal.Identity { get { return this; } }

    bool IPrincipal.IsInRole(string role)
    {
        if (string.IsNullOrEmpty(role)) return true; // assume anon OK
        lock (roleCache)
        {
            bool value;
            if (!roleCache.TryGetValue(role, out value)) {
                value = RoleHasAccess(cn, role);
                roleCache.Add(role, value);
            }
            return value;
        }
    }
    private static bool RoleHasAccess(string cn, string role)
    {
        //TODO: talk to your own security store
    }
}

答案 1 :(得分:3)

查看ASP.NET's Membership Providers。我不认为开箱即用的SQLMembershipProvider会在你的情况下工作,但它很容易推出你自己的提供商。

答案 2 :(得分:3)

我的回答可能取决于这个问题的答案: 这是一个企业应用程序,它位于具有Active Directory的网络中吗?

如果答案是肯定的,那么这些是我将提供的步骤:

1)为您的应用程序创建全局组,在我的情况下,我有一个APPUSER组和一个APPADMIN组。

2)可以在MIXED AUTHENTICATION模式下访问您的SQL Server,然后将您的APPUSER组作为SQL SERVER LOGIN分配给您的数据库,并使用适当的数据库CRUD权限,并确保您在连接字符串中使用 Trusted Connection = True 访问SQL SERVER。

此时,您的AD商店将负责身份验证。因为,您通过TRUSTED CONNECTION访问应用程序,它将把运行应用程序的任何帐户的身份传递给SQL Server。

现在,对于AUTHORIZATION(即告诉您的应用程序允许登录用户做什么),只需查询AD以获取登录用户所属的组列表即可。然后检查相应的组名,并以这种方式基于成员身份构建UI。

我的应用程序的工作方式如下:

  1. 启动应用程序,凭据基于登录用户,这是身份验证的主要方面(即他们可以登录,因此它们存在)
  2. 我获取有问题的Windows身份的所有组
  3. 我检查标准用户组 - 如果相关的Windows身份不存在此组,那么这是一个身份验证失败
  4. 我检查ADMIN用户组 - 在用户组中存在此用户组时,我修改了UI以允许访问管理组件
  5. 显示用户界面
  6. 然后我有一个PRINCIPLE对象,其中包含确定的权限/ etc,或者我使用GLOBAL变量,我可以在构建表单时确定适当的UI(即,如果我的用户不是ADMIN组的成员) ,然后我会隐藏所有DELETE按钮。)

    为什么我建议这个?

    这是一个部署问题。

    根据我的经验,大多数企业应用程序都是由网络工程师而不是程序员部署的 - 因此,认证/授权是AD的责任是有道理的,因为这是网络人员在您讨论身份验证时所采用的方式授权。

    此外,在为网络创建新用户期间,网络工程师(或负责创建新网络用户的任何人)更容易记住在IN AD中执行组分配而不是他们必须执行的事实进入十几个应用程序来解析授权的分配。

    这样做有助于获得新员工需要被授予的权限和权限的迷宫,或者需要拒绝离开公司的权限,并且在其所属的中央存储库中维护身份验证和授权(即在AD @域控制器中)电平)。

答案 3 :(得分:2)

我会看看像CSLA.net这样的东西:Expert C# 2008 Business Objects

它应该提供您需要的一切。

答案 4 :(得分:1)

WCF具有丰富的安全相关功能,同时提供授权和身份验证。 详情如下: http://msdn.microsoft.com/en-us/library/ms735093.aspx

答案 5 :(得分:0)

我认为你在这里看到一些单独的问题 - 大多数安全系统将认证和授权分开并不是偶然的。

对于身份验证,更大的问题是后勤问题。或者,这些用户是否有合理的居住地点,无论是本地应用程序,还是Active Directory,某些其他LDAP存储,甚至是其他应用程序。究竟在哪里非常重要 - 我们只需要能够稳固地识别用户,并且最好让这个任务成为别人的问题。当天结束时,你真的只需要一个唯一的标识符,以及来自Accounting的Bob实际上是来自会计的Bob。

授权是这里问题中更有趣的部分。我认为,如果真的是细粒度的,那么无论用户来自哪里,您都希望在您的应用程序中完全管理它。 Marc Gravell确实打造了至少模拟其中一些的好方法 - 使用IPrincipal和PrincipalPermission的一些自定义实现来管理事物是一种非常干净的入门方式。除此之外,您可以使用this one等技术以相当干净的方式做出更复杂的授权决策。

答案 6 :(得分:0)

我会使用术语 - &#39; RBAC&#39; (基于角色的访问控制系统)作为满足您所有需求的解决方案。

我不会详细解释&#39; RBAC&#39;在这里,我将简要描述为:

它基本上包含3个功能。

1)身份验证 - 确认用户的身份。通常通过用户帐户和密码或凭证来完成。

2)授权 - 它定义了用户在应用程序中可以执行和不可执行的操作。防爆。允许“修改订单”,但不允许“创建新订单”。

3)审核用户对应用程序的操作。 - 它跟踪用户对应用程序的操作,以及谁已授予哪些用户访问权限?

你可以在这里查看wiki上的RBAC。

https://en.wikipedia.org/wiki/Role-based_access_control

现在,关于您的要求的答案 - 可能的解决方案之一是根据您的需要扩展ASP.NET成员资格。

关于一些准备使用的框架,我建议VisualGuard为我工作,你应该检查一下,它会很容易地做你需要的所有事情,最重要的是,它管理通过管理中心控制台的所有用户,角色,权限和应用程序,并且为了定义权限,管理员不需要开发人员的知识,即他/她可以通过UI创建活动限制。

您还可以查看本文,以便更好地了解基于权限和角色的系统。

http://www.visual-guard.com/EN/net-powerbuilder-application-security-authentication-permission-access-control-rbac-articles/dotnet-security-article-ressources/role-based-access-control-source_soforum.html