Acegi学习三

运行机制

认证过程

Acegi支持多种方式的用户认证:如典型的基于数据库的认证、基于LDAP的认证、基于Yale中心认证等方式。不同的认证环境拥有不同的用户认证方式,现在我们先抛开这些具体的细节,考察一下Acegi对受限资源进行访问控制的典型过程:     1.你点击一个链接访问一个网页;     2.浏览器发送一个请求到服务器,服务器判断出你正在访问一个受保护的资源;     3.如果此时你并未通过身份认证,服务器发回一个响应提示你进行认证——这个响应可能是一个HTTP响应代码,抑或重定向到一个指定页面;     4.根据系统使用认证机制的不同,浏览器或者重定向到一个登录页面中,或者由浏览器通过一些其它的方式获取你的身份信息(如通过BASIC认证对话框、一个Cookie或一个X509证书);     5.浏览器再次将用户身份信息发送到服务器上(可能是一个用户登录表单的HTTP POST信息、也可能是包含认证信息的HTTP报文头);     6.服务器判断用户认证信息是否有效,如果无效,一般情况下,浏览器会要求你继续尝试,这意味着返回第3步。如果有效,则到达下一步;     7.服务器重新响应第2步所提交的原始请求,并判断该请求所访问的程序资源是否在你的权限范围内,如果你有权访问,请求将得到正确的执行并返回结果。否则,你将收到一个HTTP 403错误,这意味着你被禁止访问。     Acegi框架里,你可以找到对应以上大多数步骤的类,其中ExceptionTranslationFilterAuthenticationEntryPointAuthenticationProvider以及Acegi的认证机制是其中的代表者。     ExceptionTranslationFilter是一个AcegiServlet过滤器,它负责探测抛出的安全异常。当一个未认证用户访问服务器 时,Acegi将引发一个Java异常。Java异常本身对HTTP请求以及如何认证用户是一无所知的, ExceptionTranslationFilter适时登场,对这个异常进行处理,启动用户认证的步骤(第3步)。如果已认证用户越权访问一个资源, Acegi也将引发一个Java异常,ExceptionTranslationFilter则将这个异常转换为HTTP 403响应码(第7步)。可见,Acegi通过异常进行通讯, ExceptionTranslationFilter接收这些异常并作出相应的动作。     ExceptionTranslationFilter通过Java异常发现用户还未认证时,它到底会将请求重定向哪个页面以要求用户提供认证信息呢? 这通过咨询AuthenticationEntryPoint来达到目的——Acegi通过AuthenticationEntryPoint描述登录页 面。     当你的浏览器通过HTTP表单或HTTP报文头向服务器提供用户认证信息时,Acegi需要将这些信息收集到Authentication中,Acegi 认证机制描述这一过程。此时,这个新生成Authentication只包含用户提供的认证信息,但并未通过认证。 AuthenticationProvider 负责对Authentication进行认证。AuthenticationProvider究竟如何完成这一过程呢?请回忆一下上节我们所介绍的 UserDetailsUserDetailsService,大多数AuthenticationProvider通过 UserDetailsService获取和未认证的Authentication对应的UserDetails并进行匹配比较来完成这一任务。当用户认 证信息匹配时,Authentication被认为是有效的,AuthenticationProvider进一步将UserDetails中权限、 ACL等信息拷贝到Authentication Acegi通过认证机制收集到用户认证信息并填充好Authentication后,Authentication将被保存到SecurityContextHolder中并处理用户的原始请求(第7步)。     你完全可以抛开Acegi的安全机制,编写自己的Servlet过滤器,使用自己的方案构建Authentication对象并将其放置到SecurityContextHolder中。也许你使用了CMAContainer Managed Authentication:容器管理认证),CMA允许你从ThreadLocalJNDI中获取用户认证信息,这时你只要获取这些信息并将其转换为Authentication就可以了。

安全对象访问控制

Acegi称受保护的应用资源为安全对象,这包括URL资源和业务类方法。我们知道在Spring AOP中有前置增强、后置增强、异常增强和环绕增强,其中环绕增强的功能最为强大——它不但可以在目标方法被访问前拦截调用,还可以在调用返回前改变返回 的结果,甚至抛出异常。Acegi使用环绕增强对安全对象进行保护。     Acegi通过AbstractSecurityInterceptor为安全对象访问提供一致的工作模型,它按照以下流程进行工作:     1. 从SecurityContext中取出已经认证过的Authentication(包括权限信息);     2. 通过反射机制,根据目标安全对象和配置属性得到访问目标安全对象所需的权限;     3 AccessDecisionManager根据Authentication的授权信息和目标安全对象所需权限做出是否有权访问的判断。如果无权访问,Acegi将抛出AccessDeniedException异常,否则到下一步; 4. 访问安全对象并获取结果(返回值或HTTP响应); 5 AbstractSecurityInterceptor可以在结果返回前进行处理:更改结果或抛出异常。

Acegi称受保护的应用资源为安全对象,这包括URL资源和业务类方法。我们知道在Spring AOP中有前置增强、后置增强、异常增强和环绕增强,其中环绕增强的功能最为强大——它不但可以在目标方法被访问前拦截调用,还可以在调用返回前改变返回 的结果,甚至抛出异常。Acegi使用环绕增强对安全对象进行保护。     Acegi通过AbstractSecurityInterceptor为安全对象访问提供一致的工作模型,它按照以下流程进行工作:     1. 从SecurityContext中取出已经认证过的Authentication(包括权限信息);     2. 通过反射机制,根据目标安全对象和配置属性得到访问目标安全对象所需的权限;     3 AccessDecisionManager根据Authentication的授权信息和目标安全对象所需权限做出是否有权访问的判断。如果无权访问, Acegi将抛出AccessDeniedException异常,否则到下一步; 4. 访问安全对象并获取结果(返回值或HTTP响应); 5 AbstractSecurityInterceptor可以在结果返回前进行处理:更改结果或抛出异常

安全对象和一般对象的区别在于前者通过Acegi配置属性进行了描述,如“/view.jsp=PRIV_COMMON”配置属性就将 “/view.jsp”这个URL资源标识为安全对象,它表示用户在访问/view.jsp时,必须拥有PRIV_COMMON这个权限。配置属性通过 XML配置文件,注解、数据库等方式提供。安全对象通过配置属性表示为一个权限,这样,Acegi就可以根据Authentication的权限信息获知 用户可以访问的哪些安全对象。     根据安全对象的性质以及具体实现技术,AbstractSecurityInterceptor拥有以下三个实现类:  FilterSecurityInterceptor:对URL资源的安全对象进行调用时,通过该拦截器实施环绕切面。该拦截器使用Servlet过滤器实现AOP切面,它本身就是一个Servlet过滤器;l  MethodSecurityInterceptor:当调用业务类方法的安全对象时,可通过该拦截器类实施环绕切面;l  AspectJSecurityInterceptor:和MethodSecurityInterceptor类似,它是针对业务类方法的拦截器,只不过它通过AspectJ实施AOP切面。l

 

 

 

Acegi认证授权流程

1FilterToBeanProxy 负责代理请求给FilterChainProxy

2FilterChainProxy 方便的将多个Filter串联起来,如上面基本概念中提到的各种Filter,当然如果对URI进行授权保护,也可以包含FilterSecurityInterceptor。注意各Filter的顺序。

3AbstractSecurityInterceptor 调度中心。负责调用各模块完成相应功能。 FilterSecurityInterceptor URI进行拦截保护 AspectJSecurityInterceptor 对方法进行拦截保护 MethodSecurityInterceptor 对方法进行拦截保护

4AuthenticationManager 用户认证 -> AuthenticationProvider 实际进行用户认证的地方(多个) -> UserDetailsService 返回带有GrantedAuthorityUserDetail或者抛出异常。

5AccessDecisionManager(UnanimousBased/AffirmativeBased/ConsensusBased) 授权 -> AccessDecisionVoter(RoleVoter/BaseAclEntryVoter) 实际投票的Voter(多个).

6RunAsManager 变更GrantedAuthority

7AfterInvocationManager 变更返回的对象 -> BaseInvocationProvider 实际完成返回对象变更的地方(多个)

 

总结

我做好的例子只是一个很粗的模型,而且对于数据权限的解决方案觉得还不成熟,applicationContext-security-acegi.xm文件中的配置项体会不深。

我觉得通过修改数据库访问方式和添加数据权限解决方案,让我对这个系统有了切身的体会,这是个好的学习方法。

对于这个例子中的IContactManager.javaContactManager.java这两个类是代理访问类,在配置文件中需要配置的就是这两个类

学习这个系统应该对springhibernate有基础,否则可能不适合

学习这个系统是为了把它应用到我们的系统中。

学习这个系统还要明白整个系统得架构和技术,这些对我们肯定有帮助,我目前还没有什么体会 1

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值