10

假设我有一个 ASP.Net MVC 应用程序,这个应用程序 (UI) 引用了一个业务逻辑层 (BLL),而 BLL 引用了我的数据访问层 (DAL)。

我正在使用自定义成员资格和角色提供程序进行授权。

我正在尝试确定哪些层需要引用我的会员资格提供者。

在 MVC 中,您可以通过以下方式执行授权检查:

[Authorize(Roles = "SomeRoleName")]
public ActionResult Index()
{
//do something
}

在我的 BLL 中,我可能想检查用户是否也处于角色中:

public static bool IsRoleEditor(User user, Role userRole)
  {
   bool retValue = false;

   if (user.Application.AppID == UserRole.Application.AppID)
   {
        if (Roles.IsUserInRole("ModifyRoles"))
        {
           retValue = true;
        }


    return retValue;
   }

如果我这样做,我将不得不在两个层中引用和实例化 Membership 类。这是构建这样的应用程序的正确方法吗?似乎有很多冗余。

由于我有 BLL,我是否应避免使用“[Authorize(Roles = "SomeRoleName")]”属性,而是从 MVC 代码中调用 BLL 函数来检查用户是否处于角色中?如果我这样做,MVC 仍然需要对成员资格提供程序的引用以进行身份​​验证,并且无论如何都要利用登录和其他 ASP 控件,对吗?

我是否偏离了基地并朝着错误的方向前进?

4

8 回答 8

4

在我看来,这是会员/角色设计的一个弱点。

我解决这个问题的方法,例如在分布式 n 层应用程序中的 UI 和 BLL 层上具有基于角色的授权,将是在 BLL 层中公开一个服务,该服务公开相关位(GetRolesForUser 等)和通过调用服务器上的 RoleProvider 来实现。

然后在客户端实现一个自定义的 RoleProvider,通过调用 BLL 暴露的服务来实现。

这样,UI 层和 BLL 层都共享同一个 RoleProvider。UI 层可以使用当前用户角色的知识来改进 UI(例如隐藏/禁用与未经授权的功能对应的 UI 控件),并且 BLL 可以确保用户无法执行未经授权的业务逻辑。

于 2009-09-25T22:18:40.710 回答
1

很好的问题,我今天问自己同样的事情。我的一个想法(但我不确定这是否是最好的方法)是使用一个接口(例如:IRoleProvider),您可以将其传递给您的 BLL 来测试您的访问权限。

public static bool IsRoleEditor(User user, IRoleProvider rp)
{
     return (rp.IsUserInRole(user,"ModifyRoles"));
}

有了这个,你仍然可以在你的 BLL 中验证你的访问,你可以在你的单元测试中使用一个模拟来检查你的逻辑,你只需要在你的 MVC 网站中创建一个类(或在一个 baseController 类中实现它)将实现IRoleProvider 并使用 ASP.NET 授权 API 进行适当的检查。

希望这会有所帮助。

于 2009-09-15T16:38:31.783 回答
0

获取您的 User 对象以实现 IPrincipal 接口并将其扔到各个层。然后您仍然可以使用内置的 [Autorize] 属性。

尽管写于 3 年前和关于城堡的文章,但这篇文章可能会有所帮助。它开始在中途进入 IPrincipal 的东西。

HTHS
查尔斯

于 2009-09-11T00:33:17.577 回答
0

为什么不将角色传递到您的 BLL 中,这样您就不会依赖于成员资格。或者使用像 MartinB 建议的接口。

当您的利益相关者决定采用不同形式的身份验证并且您不再使用Role对象时,将来会发生什么?

例子:

IsRoleEditor(User user, string[] roles)
{
  return roles.Contains("ModifyRoles");
}
于 2009-09-25T22:02:41.993 回答
0

您是否没有错过 MVC 的要点。MVC 自然地分成几层。模型(DAL)、控制器(BLL)、视图(演示)。如果您愿意,这些可以进入不同的项目,但由于控制器具有所有业务逻辑 - 您只需要访问 RoleProvider 那里。

如果需要,然后应用存储库、模式等模式以进一步拆分。

戴维

于 2009-09-26T22:33:54.437 回答
0

调用 MVC 控制器“UI”是不合时宜的。MVC 中的“C”是BLL 的一部分,即使它引用了将调用 BLL 的类。但是,这不是您问题的重点。

我想我会通过问这个问题来解决这个问题,“你的'UI'应用程序和你的'BLL'是否有100%分离的真正要求?”。如果两个组件共享对成员/角色提供者的依赖,那么就让它如此并开始工作。

在您拔下 BLL 并插入新的 BLL 的情况下,您可以忍受对 .NET 提供程序的共享依赖。你知道这可能没问题,你的应用程序可能不会崩溃。

我认为乔上面的回答很有意义......

于 2009-09-28T04:35:09.643 回答
0

我认为你正在做的很好。

授权和身份验证应该存在于服务层中,这可能会传递到您的控制器中。

如果控制器设置了 Principal 和 Identity,然后您通过使用 MVC 属性在控制器中使用它,那么这听起来是个好主意。

将 MVC 成员资格提供程序隐藏在接口后面会很好,这样您就可以将其换成 WinForms 成员资格提供程序(例如),并且能够对您的控制器进行单元测试。

于 2009-09-28T07:17:40.300 回答
-1

角色访问通常不应该在 BLL 中。访问是用户界面的责任。

话虽如此,如上述海报所述,利用 IPrinciple 接口。您可以在线程级别访问 IPrinciple。

Thread.CurrentPrincipal
于 2009-09-19T12:42:51.507 回答