最近我做的一个项目,需要拥有ROLE_ADMIN权限的管理员能快速切换到别的用户,不需要修改或知道该用户的密码. 比如说管理员甲拥有ROLE_ADMIN权限,那么他可以不必须知道用户乙的情况下,切换到乙的身份,以乙的身份执行超过,能执行的超过以乙的权限为准。通过Acegi是可以很容易实现的。Acegi里的SwitchUserProcessingFilter可以帮助完成这个功能。下面的步骤将展示,如果配置和使用它
1. 首先要配置filter chain, 应该包含SwitchUserProcessingFilter像下面
<!– ======================== FILTER CHAIN ======================= –>
<bean id=”filterChainProxy” class=”org.acegisecurity.util.FilterChainProxy”>
<property name=”filterInvocationDefinitionSource”>
<value>
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/images/**=#NONE#
/scripts/**=#NONE#
/styles/**=#NONE#
/ **=httpSessionContextIntegrationFilter,authenticationProcessingFilter,securityContextHolderAwareRequestFilter,rememberMeProcessingFilter,anonymousProcessingFilter,
exceptionTranslationFilter,filterInvocationInterceptor,switchUserProcessingFilter
</value>
</property>
</bean>
必须注意这个过滤器必须放在filterInvocationInterceptor和FilterSecurityInterceptor的后面,不然任何角色都可以切换用户.
2. 给SwitchUserProcessingFilter定义一个bean
<bean id=”switchUserProcessingFilter” class=”org.acegisecurity.ui.switchuser.SwitchUserProcessingFilter”>
<property name=”userDetailsService” ref=”userDao” />
<property name=”switchUserUrl”><value>/j_acegi_switch_user</value></property>
<property name=”exitUserUrl”><value>/j_acegi_exit_user</value></property>
<property name=”targetUrl”><value>/mainMenu.html</value></property>
</bean>
在这里你只需要改的是targetUrl, 这个设置决定了,切换用户后将导向到那个页面.
userDao是一个一般的daoAuthenticationProvider
<bean id=”daoAuthenticationProvider” class=”org.acegisecurity.providers.dao.DaoAuthenticationProvider”>
<property name=”userDetailsService” ref=”userDao”/>
<property name=”userCache” ref=”userCache”/>
<property name=”passwordEncoder” ref=”passwordEncoder”/>
</bean>
3. 还需要在filterInvokationFilter里配置那个权限才能允许执行用户切换操作.
<bean id=”filterInvocationInterceptor” class=”org.acegisecurity.intercept.web.FilterSecurityInterceptor”>
<property name=”authenticationManager” ref=”authenticationManager”/>
<property name=”accessDecisionManager” ref=”accessDecisionManager”/>
<property name=”objectDefinitionSource”>
<value>
PATTERN_TYPE_APACHE_ANT
……
……
/j_acegi_switch_user*=ROLE_ADMIN
</value>
</property>
</bean>
4. 现在如果一个用户ROLE_ADMIN权限的管理员希望切换用户,他必须先以自己的用户名和密码登录系统。然后使用以下的连接地址
http://localhost:8080/j_acegi_switch_user?j_username=vikas
‘vikas’管理员希望切换的用户的用户名. 在这里还可以使用Acegi taglibs来确保只有拥有ROLE_ADMIN权限的用户才能使用这个地址
<authz:authorize ifAllGranted=”ROLE_ADMIN”>
<< Switch User Link Here>>
</authz:authorize>
如果用户切换成功, 当然的SecurityContextHolder将被更新和反射成被切换的用户, 此外securityContextHolder还将包含一个附件的SwitchUserGrantedAuthority, 在里面保存了原来用户的信息. 为了推出当前用户上下文并返回原来的用户身份, 可以使用下面的连接地址
http://localhost:8080/j_acegi_exit_user
这样就可以重新返回存在SwitchUserGrantedAUTHORITY的身份.
递归的切换是允许的,比如说,被切换的用户也拥有ROLE_ADMIN权限,就可以继续切换,退回用户身份是将遵循递归原则.
原文http://vikashazrati.wordpress.com