Spring Security 根据权限跳转不同画面(使用authentication-success-handler-ref流向不同action)

最近项目开发中有这样一个业务逻辑,一个登陆画面,根据不同权限跳转到不同的画面(Action) 
开始的做法是直接跳到一个调度的Action,再由这个Action去分配。 
这次开发使用了安全框架,遂希望通过安全框架去做这个调度 
于是使用authentication-success-handler-ref 
来替换default-target-url和always-use-default-target,实现这一目的 
 
国际惯例,先上代码 
Xml代码  
<http auto-config='true'  >  
  <intercept-url pattern="/public/**" access="IS_AUTHENTICATED_ANONYMOUSLY"/>  
  <intercept-url pattern="/user/**" access="ROLE_SPACE_ADMIN,ROLE_SMALL_SPACE_ADMIN,ROLE_INSTITUTION_MEMBER,ROLE_SYSTEM_ADMIN"/>    
  <intercept-url pattern="/admin/**" access="ROLE_SUPER_ADMIN"/>    
  <form-login login-page="/user/login.action"   
            authentication-failure-url="/user/login.action?msg=fault"   
            authentication-success-handler-ref="authenticationDispatcher"  
            login-processing-url="/securityLogin"/>  
  <logout logout-success-url="/user/login.action" logout-url="/securityLogout"/>  
</http>  
<beans:bean id="authenticationDispatcher" class="com.lstp.service.security.impl.LstpAuthenticationSuccessHandler">  
  <beans:property name="authDispatcherMap">  
    <beans:ref local="dispatcherMap"/>  
  </beans:property>  
</beans:bean>  
<beans:bean id="dispatcherMap" class="java.util.HashMap">  
  <beans:constructor-arg>  
    <beans:map>  
      <beans:entry key="ROLE_SPACE_ADMIN" value="/user/userSpace.action"/>  
      <beans:entry key="ROLE_SMALL_SPACE_ADMIN" value="/user/userSpace.action"/>  
      <beans:entry key="ROLE_INSTITUTION_MEMBER" value="/user/userSpace.action"/>  
      <beans:entry key="ROLE_SYSTEM_ADMIN" value="/admin/adminSpace.action"/>  
      <beans:entry key="ROLE_SUPER_ADMIN" value="/admin/adminSpace.action"/>  
      </beans:map>  
  </beans:constructor-arg>  
</beans:bean>  
 
authentication-success-handler-ref="authenticationDispatcher"是至关重要的,当登陆成功会调用实现AuthenticationSuccessHandler接口的onAuthenticationSuccess方法. 
下面是实现类 
Java代码  
package com.lstp.service.security.impl;  
  
import java.io.IOException;  
import java.util.Collection;  
import java.util.Map;  
  
import javax.servlet.ServletException;  
import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpServletResponse;  
import org.springframework.security.core.Authentication;  
import org.springframework.security.core.GrantedAuthority;  
import org.springframework.security.core.authority.GrantedAuthorityImpl;  
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;  
import org.springframework.util.Assert;  
  
/** 
 * 权限登录成功句柄 
 * 该类为平台成功跳转到多个入口提供依据 
 * @author ryuu-kk 
 * 
 */  
public class LstpAuthenticationSuccessHandler implements AuthenticationSuccessHandler {  
  
    /** 
     * url参数 
     */  
    private Map<String, String> map;  
    /** 
     * 多role选择,默认取得权限表第一个权限 
     */  
    private boolean isFirst = true;  
    @Override  
    public void onAuthenticationSuccess(HttpServletRequest request,  
            HttpServletResponse response, Authentication authentication)  
            throws IOException, ServletException {  
        Assert.notNull(map, "AuthInterceptMap is null!");  
        String url = "";  
        Collection<GrantedAuthority> authCollection = authentication.getAuthorities();  
  
        if (authCollection.isEmpty()) {  
            return;  
        }  
        //对于一个登录用户有多种角色,只取得第一个  
        if (isFirst) {  
            GrantedAuthority[] a = new GrantedAuthorityImpl[]{};  
            url = map.get(authCollection.toArray(a)[0].toString());  
            response.sendRedirect(request.getContextPath() + url);  
            return;  
        }  
        //选择取得最后一个role掉转;这里一个用户的多个角色较少  
        //迭代的速度比转换成数组的速度要快  
        for (GrantedAuthority auth : authCollection) {  
            url = map.get(auth.getAuthority());  
        }  
        response.sendRedirect(url);  
    }  
      
    /** 
     * 权限跳转依据 
     * @param map 参数 
     *  key:url 
     *  value:role 
     */  
    public void setAuthDispatcherMap(Map<String, String> map) {  
        this.map = map;  
    }  
  
    /** 
     * 多种角色方案 
     * 设置是否只取得第一个role 
     * @param isFirst true:多种角色只取第一个,false:取得最后一个 
     */  
    public void setMultipleAuth(boolean isFirst) {  
        this.isFirst = isFirst;  
    }  
}  
posted @ 2013-05-01 14:37  linux,dev  阅读(1677)  评论(0编辑  收藏  举报