在C#中编写自定义属性,例如ASP.Net MVC授权属性

5
我喜欢ASP.Net MVC的授权属性,我可以扩展它并构建自己的逻辑来装饰我的控制器。但是,
在我的架构中,我有一个公共服务层(C#类库)。最终用户可以通过ASP.Net MVC网站或通过我的公开REST WCF Web服务层访问我的应用程序。 我的ASP.NET MVC应用程序和REST WCF服务层都会访问我的公共服务层。
我希望授权发生在这个公共服务层而不是ASP.Net MVC控制器或我的公开REST服务层中。
我能否创建类似于ASP.Net MVC授权属性的东西来装饰我的公共C#类库中的方法?该属性将接受参数,并决定当前用户是否有权限执行该功能?
谢谢和问候, Ajay
4个回答

5
你可以使用AOP库(比如PostSharp)来实现你想要的功能。虽然比在mvc中使用Authorize属性更为复杂,但仍然相当简单。请参考http://www.postsharp.org/

非常感谢。PostSharp看起来不错。我正在深入研究它。希望我的架构能得到很好的提升。 - Ajay

3

另一种处理方法是在您的服务层中使用[PrincipalPermission]属性。这可以防止调用者在未经授权的情况下执行方法(或访问整个类)。


1
不,AuthorizeAttribute 起作用是因为 MVC 框架在调用方法之前明确地调用它。类似的功能对于您的服务层只有在客户端显式调用它时才能起作用。假设即使是一个有良好意图的客户端也总是记得查找属性并调用它是不合理的。WCF 有自己的安全性。您应该使用它而不是编写自己的安全性。

如果我将授权逻辑放在我的REST API中,那么我还必须在控制器中进行重复操作。这就是为什么我需要在服务层(不是WCF,只是C#类库)中做一些事情。 - Ajay
你不需要复制任何东西。WCF和ASP.NET都会告诉你谁连接了。你只需要将这个转化为他们可以做什么。这段代码可以共享。我只是说你不应该使用自定义属性来实现它。使用框架中已经内置的功能即可。 - Craig Stuntz
如果他决定添加另一个前端,那该怎么办?他将不得不再次编写所有这些属性。如果他更改了一些规则,比如哪些组可以调用方法,他将不得不更改所有前端。有可能创建这样的属性(使用aop),我相信Ajay应该这样做,因为只有这样他才能确保授权对于所有前端都是一致的,并且他可以安全地添加另一个前端而不必担心所有这些授权问题,这些问题对于所有前端都是共同的... - maciejkow
maciejkow:我并没有建议使用属性。我建议使用内置的身份管理和共享身份->权限代码。如果您认为我建议写任何东西超过一次,请重新阅读我写的内容。 - Craig Stuntz

0

这应该不难做到 - 有几个地方可以反射出属性并相应地处理它:

  • 在 Global.asx 中的应用程序启动时,您可以自定义视图的路由和位置

  • 基础 ASP.Net 请求事件仍然会触发,因此您可以覆盖其中之一

  • 创建自己的基本控制器并覆盖 OnActionExecuting


更新以下评论

啊,我明白了。在这种情况下,如果您正在进行直接调用,则应查看代码访问安全性,我认为它涵盖了您的意思。

或者,如果您正在使用某种工厂模式,则自定义属性可能是有意义的 - 然后获取工厂的反射调用可以检查属性。

如果您没有使用反射来检索类或调用方法(这本质上就是MVC中路由所做的),那么您将没有机会检查属性。


1
在ASP.Net MVC中,我可以这样做,我需要在C#类库中做同样的事情,以便任何调用C#方法的人都应该进行授权检查。谢谢。 - Ajay

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接