假设我有一个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仍然需要引用成员资格提供程序进行身份验证,无论如何要利用Login和其他ASP控件,对吧?

我离开基地并向错误的方向前进吗?

有帮助吗?

解决方案

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

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

然后在客户端上实现自定义RoleProvider,该客户端通过调用BLL公开的服务来实现。

通过这种方式,UI层和BLL层共享相同的RoleProvider。 UI层可以使用当前用户角色的知识来改进UI(例如,隐藏/禁用与未授权特征相对应的UI控件),并且BLL可以确保用户无法执行 他们未获得授权的业务逻辑。

其他提示

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

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

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

希望这会有所帮助。

获取User对象以实现IPrincipal接口并将其抛出图层。然后,您仍然可以使用内置的[Autorize]属性。

虽然写于3年前,关于城堡,这篇文章可能有所帮助。它开始进入IPrincipal的一半。

HTHS结果 查尔斯

为什么不将角色传递给BLL,这样您就不会依赖会员资格。或者使用像MartinB建议的界面。

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

示例:

IsRoleEditor(User user, string[] roles)
{
  return roles.Contains("ModifyRoles");
}

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

然后应用诸如存储库,模式等模式,以便在需要时进一步拆分。

戴维

调用MVC控制器'UI'是不合适的.MVC中的'C'是BLL的 part ,即使它引用了的类>会打电话给BLL。但是,这不是你问题的重点。

我想我会通过提出这样一个问题来解决这个问题,“是否真的要求将'UI'应用和'BLL'分开?”。如果两个组件共享成员/角色提供者的依赖关系,那么就这样开始工作。

如果你拔掉你的BLL并插入一个新的BLL,那么你可以使用对.NET提供程序的共享依赖。你知道这可能没事,你的应用可能不会崩溃。

我认为Joe的上述答案虽然很有意义......

我认为你做得很好。

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

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

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

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

据说,如上述海报所述,利用IPrinciple界面。您可以在线程级别访问IPrinciple。

Thread.CurrentPrincipal
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top