2.4. 安全对象
如果你熟悉AOP,你会知道有很多种advice可用:before, after, throws 和 around。around advice非常有用,因为它能够选择是否选择是否执行一个方法调用,是否修改返回值,以及是否抛出异常。Acegi Security对方法调用和web请求都提供around advice。我们使用AOP联盟实现对方法调用的around advice,对于web请求的around advice则是使用标准的过滤器(Filter)。
对于那些不熟悉AOP的人来说,关键是要理解Acegi Security能够帮助你保护方法调用以及web请求。大多数人对保护他们服务层的方法调用感兴趣。这是因为在当前的J2EE应用中,服务层包含了大多数的业务逻辑(声明,作者不赞成这种设计,反而支持正确封装的领域模型以及DTO,assembly, facade 以及 transparent persistence patterns,而不是当前主流的贫血模型,我们将在这里讨论)。如果你需要保护service层的方法调用,使用标准的Spring AOP平台(或者被成为AOP 联盟(AOP Alliance))就足够了。如果你需要直接对领域模型进行保护,那么可以考虑使用AspectJ。
你可以选择对使用AspectJ 或者AOP联盟(AOP Alliance)对方法进行授权,或者你可以选择使用过滤器(filter)来对web请求进行授权。你将0个,1个,2个或者3个这些方法一起使用。主流的用法是执行一些web请求授权,以及在服务层使用AOP联盟(AOP Alliance)对一些方法调用授权。
Acegi Security使用“安全对象”(secure object)这个词来指任何能够将安全应用于其上的对象。每个Acegi Security支持的安全对象都有自己的类,它是AbstractSecurityInterceptor的子类。重要的一点是,如果一个principal通过认证,当AbstractSecurityInterceptor执行的时候,SecurityContextHolder中要包含一个有效的Authentication。
AbstractSecurityInterceptor提供一个固定的工作流程来处理安全对象请求。这个工作流程包括查找和当前请求相关联的“配置属性(configuration attributes)”。配置属性(configuration attributes)可以被认为是对被AbstractSecurityInterceptor使用的类有特殊含义的字符串。他们通常针对AbstractSecurityInterceptor使用XML进行配置。反正,AbstractSecurityInterceptor会询问AccessDecisionManager “这是配置属性(configuration attributes),这是当前的认证对象(Authentication object),这是当前请求的详细信息-那么这个特定的principal可以执行这个特定的操作吗?”。
假如AccessDecisionManager判定允许这个请求,那么AbstractSecurityInterceptor一般来说就继续执行请求。虽然这样,用户在少数情况之下可能需要替换SecurityContext中的Authentication,可以通过AccessDecisionManager调用一个RunAsManager来实现。在某些不常见的情形下这将非常有用,例如服务层的方法需要用另一种标识(身份)来调用远程系统。这可能有所帮助,因为Acegi Security自动在不同的服务器之间传播安全标识(假设你正确配置了RMI或者HttpInvoker remoting protocol client)。
随着安全对象处理和返回-意味着方法调用完毕或者过滤器链(filter chain)处理完毕-AbstractSecurityInterceptor有最后的机会来处理调用。这时,AbstractSecurityInterceptor可能会修改返回的对象。我们可能要这样做,因为授权判断不能在安全对象调用途中执行。由于高度的可插拔性,如果需要AfterInvocationManager将控制权交给AfterInvocationManager来实际修改对象。这个类甚至可以彻底替换对象,或者抛出异常,或者根本不修改它。
因为是AbstractSecurityInterceptor中心模版类,看起来第一副插图该献给它。(译注:原手册里的图画的太丑陋了,我用jude重新画了一遍)
<!--[if gte vml 1]><v:shapetype id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f"> <v:stroke joinstyle="miter" /> <v:formulas> <v:f eqn="if lineDrawn pixelLineWidth 0" /> <v:f eqn="sum @0 1 0" /> <v:f eqn="sum 0 0 @1" /> <v:f eqn="prod @2 1 2" /> <v:f eqn="prod @3 21600 pixelWidth" /> <v:f eqn="prod @3 21600 pixelHeight" /> <v:f eqn="sum @0 0 1" /> <v:f eqn="prod @6 1 2" /> <v:f eqn="prod @7 21600 pixelWidth" /> <v:f eqn="sum @8 21600 0" /> <v:f eqn="prod @7 21600 pixelHeight" /> <v:f eqn="sum @10 21600 0" /> </v:formulas> <v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect" /> <o:lock v:ext="edit" aspectratio="t" /> </v:shapetype><v:shape id="_x0000_i1025" type="#_x0000_t75" style='width:423pt; height:270.75pt'> <v:imagedata src="file:///C:\WINDOWS\TEMP\msohtml1\01\clip_image001.jpg" o:title="ch2-1" /> </v:shape><![endif]--><!--[if !vml]--><!--[endif]-->
图1 关键“安全对象”模型
只有那些希望实现全新的对请求进行截取截取和授权方式的开发者才需要直接使用安全对象。例如,可能构建一个新的安全对象安全调用一个消息系统。任何需要安全并且能够提供一种截取调用的方式(例如AOP around advice semantics)的东西都可以成为安全对象。虽然如此,大部分的Spring应用都会只是透明应用当前支持的三种安全对象类型(AOP Alliance MethodInvocation, AspectJ JoinPoint 和 web request FilterInterceptor)。
2.5. 结论
恭喜!你已经获取了Acegi Security足够的概括性的图景来开始着手你的项目。我们探究了共享组件,认证过程,以及对“安全对象”的通用授权概念。手册中的余下部分你可能用到也可能用不到,可以按照任意顺序阅读。
3 楼 lvjinhua 2009-10-02 22:51
2 楼 yangke_love 2008-12-31 15:33
1 楼 yangke_love 2008-12-31 15:33