Spring Security 根据权限跳转不同画面(使用authentication-success-handler-ref流向不同action)
2013-05-01 14:37
495 查看
最近项目开发中有这样一个业务逻辑,一个登陆画面,根据不同权限跳转到不同的画面(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;
}
}
开始的做法是直接跳到一个调度的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;
}
}
相关文章推荐
- Spring Security 根据权限跳转不同画面(使用authentication-success-handler-ref流向不同action)
- spring security的权限页面标签可以根据 ifAnyGranted="ROLE_SYSTEM" 这个不同的权限觉得在<sec:authorize的作用不作用,就相当于c:if标签的作用
- 2、nginx中使用Lua根据url参数长度跳转到不同的upstream
- jquery根据不同按钮跳转action
- 【Spring实战】----Security4.1.3实现根据请求跳转不同登录页以及登录后根据权限跳转到不同页配置
- thinkphp5登录并保存session、根据不同用户权限跳转不同页面
- Action输出不同视图的方法(根据结果跳转到不同页面)
- spring security 登录根据用户角色跳转到不同的页面
- 【Spring实战】----Security4.1.3实现根据请求跳转不同登录页以及登录后根据权限跳转到不同页配置
- JAX-WS使用Handler实现简单的WebService权限验证
- SharePoint 2010 利用JavaScript根据用户使用的语言应用不同的样式
- Kotlin android简单Activity跳转、handler和thread简单配合使用
- 在MFC GridCtrl中使用CGridCellCheck类根据GetCheck()状态做不同处理的实现
- JS判断请求来自Android手机还是iPhone手机,根据不同的手机跳转到不同的链接。
- 在Spring Boot中使用Spring Security实现权限控制
- MVC扩展控制器工厂,通过实现IControllerFactory,根据action名称生成不同的Controller
- 使用Forms设置不同角色具有不同的权限
- 使用Spring Security实现权限管理
- Nginx根据不同浏览器语言配置页面跳转的方法
- ActionBar简单使用——添加搜索按钮;让不同的Activity上显示不同的ActionBar;添加Tab标签;实现DrawerLayout并用ActionBarDrawerToggle控制