处理安全性并解耦

发布于 2024-08-05 02:54:29 字数 1230 浏览 8 评论 0原文

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

1)数据访问层
2)业务层
3)UI

我尝试保持类解耦,因此在业务层上我为数据访问类创建了接口,如下所示:

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

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

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

   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 程序集)。

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

I am trying to design an application in 3 layers :

1) Data access layer
2) business layer
3) UI

I try to keep classes decoupled so on the business layer I have created interfaces for the Data access classes like this :

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

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

and i pass the interface as param to the service constructor :

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

But on the CountryService for example I need to load the current user and his permissions so I can check if the operation can be applied :

    public Country GetCountry(int ID)
    {

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

    }

That means I have to instantiate the SecurityDataAccess object and pass it to the constructor of the SecurityService on my business layer assembly which I try to avoid for keeping objects decoupled. Right now I even don't have a reference to any DataAccess assembly on my business assembly.

I am thinking of using an IoC container here. Using external configuration I could get the right class/assembly from a config file. But I am not sure that is the right solution because it is said that IoC containers should be used in one place to keep things simple and it should be the top level assembly (the UI assembly) most of the time.

Anybody has a suggestion for solving this problem ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

遥远的绿洲 2024-08-12 02:54:29

为什么不将安全服务添加到 Country 服务的构造函数中?这样,IOC 容器可以解决依赖性并在需要时注入安全性。这意味着 IOC 容器将负责构建您的 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,如果无效则抛出异常,或者在链中的下一个链接中传递请求(您还可以以这种方式动态添加日志记录,或者计时或其他方式)

Why not add the security service into the constructor of the Country service? That way the IOC Container could resolve the dependency and inject the security if it is needed. That mean the IOC Container would take care of constructing your CountryService object. And you would use the container to get all Services.

Another option could be to "normalize" your repository a bit...

Trim it down to it only has 4-5 basic functions that are identical for all repositories, then use generics to make them all look alike, so no

UpdateCountry(...)
but
Update(T object)

Something like this:
http://codebetter.com/blogs/gregyoung/archive/2009/01/16/ddd-the-generic-repository.aspx

Then you can use a Chain of reponsibilty pattern to place your security code before the DB Code ( http://en.wikipedia.org/wiki/Chain-of-responsibility_pattern )

So you could have a SecurityChecker that validates access, throws an exception if invalid, or passes down the request in the next link in the chain (You can also add a logging dynamically that way, or timing or whatever)

拥有 2024-08-12 02:54:29

您需要在数据访问层实现安全性吗?如果你按照 Heiko 的建议将安全服务移至业务层。换句话说,在业务层执行安全性,就可以完全避免 IoC 问题。

Do you need to implement security in the Data Access layer? If you move your security service to the business layer as Heiko suggests. In other words, perform security in the business layer and you avoid the IoC issue altogether.

披肩女神 2024-08-12 02:54:29

这可能有点偏离主题,如果是的话,我很抱歉,我是一名潜伏的 Java EE 程序员。在我看来,方法的授权最好在基础设施中以声明方式解决。

这篇文章似乎表明 .Net ,就像 Java EE 提供了一种以声明方式控制访问的工具。这种方法对你有用吗?

This may be off-beam, apologies if it is, I'm a lurking Java EE programmer. It seems to me that authorisation is of methods is better addressed in the infrastructure, declaratively.

This article appears to suggest that .Net, like Java EE offers a facility to control access declaratively. Does this approach work for you?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文