精华帖 (0) :: 良好帖 (7) :: 新手帖 (10) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-06-08
最后修改:2009-10-19
public class TestAction extends ActionSupport { @ActionRoles( { "ROLE_ADMIN", "ROLE_USER" }) public String test() throws Exception { return SUCCESS; } } 进行以上配置后,只有拥有了“ROLE_ADMIN”,“ROLE_USER”两种角色的用户才能访问test这个action。 我们都知道Spring security拥有注解@Secured可以保护领域方法,但却无法实现Action的保护,因为Struts2中Action的执行已经涉及到Struts2本身的拦截器,已经与Spring Security过滤器无关了。所以想拥有上述功能,就只好自己写了。 现在你就能拥有! 首先,定义一个简单的注解: @Target(METHOD) @Retention(RUNTIME) public @interface ActionRoles { String[] value(); } 然后,写个Struts2的拦截器,对请求进行拦截,像这样: /** * @author PanHuizhi * */ public class SpringSecurityInterceptor extends AbstractInterceptor { private static final long serialVersionUID = 1L; private String loginPage; private String accessDeniedPage; public String intercept(ActionInvocation actionInvocation) throws Exception { ActionRoles actionRole = getActionRole(actionInvocation); UserDetails userDetails = getUserDetails(); Object savedPath = getPath(); if (savedPath != null && userDetails != null) { removePath(); return "!" + savedPath; } if (actionRole == null) { return actionInvocation.invoke(); } if (userDetails == null) { putPath(); return "!" + loginPage; } if (!isAccessable(userDetails.getAuthorities(), actionRole.value())) { return "!" + accessDeniedPage; } return actionInvocation.invoke(); } private ActionRoles getActionRole(ActionInvocation actionInvocation) { ActionProxy actionProxy = actionInvocation.getProxy(); Object action = actionProxy.getAction(); String method = actionProxy.getMethod(); Method actionMethod = null; try { actionMethod = action.getClass().getMethod(method); } catch (SecurityException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } return actionMethod.getAnnotation(ActionRoles.class); } private UserDetails getUserDetails() { UserDetails userDetails = null; try { userDetails = (UserDetails) SecurityContextHolder.getContext() .getAuthentication().getPrincipal(); } catch (Exception exception) { } return userDetails; } private void putPath() { ActionContext.getContext().getSession().put("SAVED_SERVLET_PATH", ServletActionContext.getRequest().getServletPath()); } private String getPath() { return (String) ActionContext.getContext().getSession().get( "SAVED_SERVLET_PATH"); } private void removePath() { ActionContext.getContext().getSession().remove("SAVED_SERVLET_PATH"); } private boolean isAccessable(GrantedAuthority[] grantedAuthority, String[] roles) { List<String> grantedAuthorities = new ArrayList<String>(); for (int i = 0; i < grantedAuthority.length; i++) { grantedAuthorities.add(grantedAuthority[i].getAuthority()); } for (int i = 0; i < roles.length; i++) { if (!grantedAuthorities.contains(roles[i])) { return false; } } return true; } public void setLoginPage(String loginPage) { this.loginPage = loginPage; } public void setAccessDeniedPage(String accessDeniedPage) { this.accessDeniedPage = accessDeniedPage; } } 最后,你只要做简单配置就大功告成了 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <package name="app-default" extends="struts-default"> <result-types> <result-type name="direct" class="org.apache.struts2.spring.security.dispatcher.DirectResult"></result-type> </result-types> <interceptors> <interceptor name="springSecurityInterceptor" class="org.apache.struts2.spring.security.interceptor.SpringSecurityInterceptor"> <param name="loginPage">/login.action</param> <param name="accessDeniedPage">/403.jsp</param> </interceptor> <interceptor-stack name="appDefaultStack"> <interceptor-ref name="springSecurityInterceptor" /> <interceptor-ref name="defaultStack" /> </interceptor-stack> </interceptors> <default-interceptor-ref name="appDefaultStack" /> <global-results> <result name="*" type="direct" /> </global-results> </package> </struts> 你需要根据实际情况修改“/login.action”,“/403.jsp”,接着只要你的Struts Package 都继承这个app-default包就行了啊,是不是很简单,保护Struts2的Action你现在就能拥有。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2009-06-08
引用 经过测试发现,这个东西做的很不完善,很希望大家多多挑毛病,以后改进喔。。。。。 不完善就拿上来,为什么不做的完善再拿来show!! |
|
返回顶楼 | |
发表时间:2009-06-08
kjj 写道 引用 经过测试发现,这个东西做的很不完善,很希望大家多多挑毛病,以后改进喔。。。。。 不完善就拿上来,为什么不做的完善再拿来show!! 谦虚都不懂,算了,我把它删了,还不行嘛? |
|
返回顶楼 | |
发表时间:2009-06-08
最后修改:2009-06-08
phz50 写道 kjj 写道 引用 经过测试发现,这个东西做的很不完善,很希望大家多多挑毛病,以后改进喔。。。。。 不完善就拿上来,为什么不做的完善再拿来show!! 谦虚都不懂,算了,我把它删了,还不行嘛? 引用 我们都知道Spring security拥有注解@Secured可以保护领域方法,但却无法实现Action的保护 大名鼎鼎的ss 竟然无法保护action ,怪哉!! 看来这句才知道,说得没错,果然不完善!! |
|
返回顶楼 | |
发表时间:2009-06-08
最后修改:2009-06-08
引用 大名鼎鼎的ss 竟然无法保护action ,怪哉!!
看来这句才知道,说得没错,果然不完善!! |
|
返回顶楼 | |
发表时间:2009-06-09
LZ已经提供了很好的思路,但是按这个思路走下去,不搞的几天出不来东西啊。
|
|
返回顶楼 | |
发表时间:2009-06-09
spring针对url的保护不就是针对action的保护吗,有这必要在搞一遍注释?
|
|
返回顶楼 | |
发表时间:2009-06-09
最后修改:2009-06-09
cris_jxg 写道 spring针对url的保护不就是针对action的保护吗,有这必要在搞一遍注释?
提的很好,不过,一个Action可以针对不同Url,而且Url是可能经常修改的,一旦修改了,就要修改它保护的配置了,维护起来很麻烦,特别是当Url较多时,而针对Action本身注解,一旦更改了Action或Url不用修改其它,维护起来比较方便和直观。当然也可以一起使用它们,并不冲突的。 |
|
返回顶楼 | |
发表时间:2009-06-09
适用面太窄了,你这个是在代码里写死的,如果客户要调整权限怎么办
|
|
返回顶楼 | |
发表时间:2009-06-09
fuwang 写道 适用面太窄了,你这个是在代码里写死的,如果客户要调整权限怎么办
?,可能你还不太明白,这个东西的功能,权限是通过对Action方法注解设置的,随时可以更改的,如把,@ActionRoles( { "ROLE_ADMIN", "ROLE_USER" }) ,改成@ActionRoles( { "ROLE_ADMIN"}) ,权限就改了啊 |
|
返回顶楼 | |