处理安全性并解耦

时间:2009-09-12 07:44:02

标签: asp.net architecture oop decoupling

我正在尝试设计3层应用程序:

1)数据访问层
2)业务层
3)用户界面

我尝试将类解耦,以便在业务层上为数据访问类创建接口,如下所示:

public interface ICountryRepository:IRepository 
{
    Country  GetCountry(int ID);

    int CreateCountry(Country obj);
    Boolean UpdateCountry(Country obj);
    Boolean DeleteCountry(Country obj);
    ...
    ...
 }

我将接口作为param传递给服务构造函数:

   public CountryService(ICountryRepository repository,ILanguageRepository lang_repository)
   {       
    ....
   }

但是在CountryService上我需要加载当前用户及其权限,以便我可以检查是否可以应用该操作:

    public Country GetCountry(int ID)
    {

        if securityService.UserHasPermission(currentUser, GetPermission("CanGetCountry"))
        {
           return repository.GetCountry(ID);
        }
        else
        { 
           Throw(New SecurityException("No permissions for that operation ...."))
        }

    }

这意味着我必须实例化SecurityDataAccess对象并将其传递给我的业务层程序集上的SecurityService的构造函数,我试图避免将对象分离。现在我甚至没有在业务程序集上引用任何DataAccess程序集。

我在考虑在这里使用IoC容器。使用外部配置我可以从配置文件中获取正确的类/程序集。但我不确定这是否是正确的解决方案,因为据说IoC容器应该在一个地方使用以保持简单,并且它应该是大多数时间的顶级程序集(UI程序集)。

有人建议解决这个问题吗?

3 个答案:

答案 0 :(得分:1)

为什么不将安全服务添加到Country服务的构造函数中?这样,IOC容器可以解决依赖关系,并在需要时注入安全性。这意味着IOC Container将负责构建您的CountryService对象。并且您将使用容器来获取所有服务。

另一种选择可能是对您的存储库进行“规范化”......

将其修剪为只有4-5个基本功能,对于所有存储库都是相同的,然后使用泛型使它们看起来都相似,所以没有

UpdateCountry(...) 但 更新(T对象)

这样的事情: http://codebetter.com/blogs/gregyoung/archive/2009/01/16/ddd-the-generic-repository.aspx

然后,您可以使用可复制链模式将安全代码放在数据库代码之前(http://en.wikipedia.org/wiki/Chain-of-responsibility_pattern

因此,您可以拥有一个验证访问权限的SecurityChecker,如果无效则抛出异常,或者在链中的下一个链接中传递请求(您也可以通过这种方式动态添加日志,或者计时或其他)

答案 1 :(得分:0)

您是否需要在数据访问层中实施安全性?如果您将安全服务移动到业务层,Heiko建议。换句话说,在业务层中执行安全性并完全避免IoC问题。

答案 2 :(得分:0)

这可能是一个离线的,如果它是道歉,我是一个潜伏的Java EE程序员。在我看来,在基础设施中,声明性地更好地解决了授权方法。

这个article似乎表明.Net与Java EE一样,提供了一种以声明方式控制访问的工具。这种方法对你有用吗?