本文共 4227 字,大约阅读时间需要 14 分钟。
Acegi 设计概述
作者: cac,作者保留版权,转载请注明出处。
第一步, 认证(authentication)。Acegi调用AuthenticationManager(认证管理器)来对当前请求登陆系统用户进行验证,AuthenticationManager负责委托一个或多个Provider(认证提供者),并逐一遍历每个Provider,直到某一个Provider能够成功的验证用户的身份。Provider成功验证用户身份后,会返回一个Authentication(证明), Authentication中包括Principal(用户名),Credentials(通常是密码),Authorities(该用户所拥有的权限)。这样就完成了身份验证的步骤。
第二步,授权(authorization)。当Acegi获得Authentication后,也就确定了用户的身份。每当用户请求访问某受保护资源时,Acegi会调用AccessDecisionManager(访问决策管理器)来决定用户的Authentication是否有恰当的权限来访问当前访问的受保护资源,有则授权用户通过,无则抛出错误信息,以达到访问控制的目的。
Acegi的FilterChainProxy提供了一种很好的方式,使你不需要在web.xml配置Filters,而在Spring配置文件中加入, 从而能充分利用Spring IOC的优势。
FilterChainProxy其实也只是一个扩展后的Filter,它负责委托Spring中的各个实现了javax.servlet.Filter接口的Bean来执行过滤功能。 如httpSessionContextIntegrationFilter, authenticationProcessingFilter, filterInvocationInterceptor等。
在web.xml中的配置FilterToBeanProxy:
<filter>
<filter-name>Acegi Filter Chain Proxy</filter-name>| <filter-class>org.acegisecurity.util.FilterToBeanProxy</filter-class> <init-param> <param-name>targetClass</param-name> <param-value>org.acegisecurity.util.FilterChainProxy</param-value> </init-param></filter><filter-mapping> <filter-name>Acegi Filter Chain Proxy</filter-name> <url-pattern>/*</url-pattern></filter-mapping>在Spring配置文件中相应的FilterChainProxy Bean:
<bean id="filterChainProxy" class="org.acegisecurity.util.FilterChainProxy">
<property name="filterInvocationDefinitionSource"> <value> CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON PATTERN_TYPE_APACHE_ANT /**=httpSessionContextIntegrationFilter,logoutFilter,authenticationProcessingFilter,securityContextHolderAwareRequestFilter, rememberMeProcessingFilter,anonymousProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor </value> </property></bean>Acegi的异常管理机制做得不错,基本上可以满足权限管理需求。在其结构基础上继承实现自己的异常类也是很方便的。
所有Acegi的异常都是在 AcegiSecurityException 上继承而来的,其中最主要的是 AuthenticationException 和 AccessDeniedException。
这里需要注意的是 AcegiSecurityException 继承了Spring的 NestedRuntimeException,而NestedRuntimeException又是继承RuntimeException的。
所以抛出的时候不需要throws, 而捕捉的时候需要专门catch RuntimeException。AuthenticationException 是所有授权相关的异常的父类,当用户身份验证失败时就会抛出这个异常。
AccessDeniedException 是所有认证相关的异常的父类,当资源被拒绝访问时就会抛出这个异常。
在Acegi 中,通过ExceptionTranslationFilter(异常转换过滤器)来对各种异常进行捕获和处理,并重定向到不同的错误信息显示页面。
如遇到AuthenticationException 就会重定向到登陆页面,遇到AccessDeniedException 就会无权访问资源页面。你还可以继承ExceptionTranslationFilter基础上覆盖handleException方法来实现你自己的系统中异常的处理。
<bean id="exceptionTranslationFilter" class="org.acegisecurity.ui.ExceptionTranslationFilter">
<property name="authenticationEntryPoint"> <bean class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint"> <property name="loginFormUrl" value="/login.jsp" /> <property name="forceHttps" value="false" /> </bean> </property> <property name="accessDeniedHandler"> <bean class="org.acegisecurity.ui.AccessDeniedHandlerImpl"> <property name="errorPage" value="/accessDenied.jsp" /> </bean> </property></bean>