`
liuqq
  • 浏览: 52060 次
  • 性别: Icon_minigender_1
  • 来自: 大连
社区版块
存档分类
最新评论

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

阅读更多
最近项目开发中有这样一个业务逻辑,一个登陆画面,根据不同权限跳转到不同的画面(Action)
开始的做法是直接跳到一个调度的Action,再由这个Action去分配。
这次开发使用了安全框架,遂希望通过安全框架去做这个调度
于是使用authentication-success-handler-ref
来替换default-target-url和always-use-default-target,实现这一目的


国际惯例,先上代码
<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方法.
下面是实现类
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;
	}
}


分享到:
评论
2 楼 java_pad 2011-11-03  
很好用啊!
1 楼 viano 2011-08-12  
好像不合适!

环境 spring + spring security3.0

相关推荐

Global site tag (gtag.js) - Google Analytics