用过Spring Security的朋友一定不会陌生,有个@Secured注解,可以将其加在Service层的方法上,保护某个方法的安全,确保只有授权的角色可以调用该方法。
但是,如果要对Struts2的Action方法进行保护呢?看似加注解是个不合理的需求。但是,有些情况下,例如,一个命名空间下用星号匹配有多个角色,而用精确地址匹配又导致数据太多,数据库不太好维护。在这种情况下,如果一个Action地址,确定以后不会太更换访问角色的话,可以考虑用注解来保护。
可以将命名空间下的全部地址匹配为星号。然后用注解保护该命名空间下的个别Action地址。
首先是一个注解类。 @Target(METHOD) @Retention(RUNTIME) public @interface ActionRoles { SysRole[] value(); }
注解里面是一个枚举类,代表了系统的所有角色枚举。 然后是Struts2的拦截器,在该拦截器内,通过反射,得到加在Action方法注解上的用户角色数组。其中,还通过SpringSecurityUtils取得当前登录的用户,并拿到登录用户的角色,通过和actionRoles循环比较,得到用户是否有授权。 public class AuthorityInterceptor extends MethodFilterInterceptor { private static final long serialVersionUID = -1070565846576510701L; @Override protected String doIntercept(ActionInvocation actionInvocation) throws Exception { User currentUser = SpringSecurityUtils.getCurrentUser(); if (currentUser != null) { try { Object action = actionInvocation.getAction(); ActionProxy actionProxy = actionInvocation.getProxy(); Method method = action.getClass().getMethod(actionProxy.getMethod()); ActionRoles actionRoles = method.getAnnotation(ActionRoles.class); if (actionRoles != null) { boolean authorized = false; SysRole[] sysRoles = actionRoles.value(); for (SysRole sysRole : sysRoles) { if (SysRole.equals(currentUser.getRoleName(), sysRole)) { authorized = true; break; } } if (!authorized) { return BaseActionSupport.UNAUTHORIZED; } } } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } } return actionInvocation.invoke(); } } 最后一步,很简单啦,在Struts2的Action方法上面加上注解。 @ActionRoles({SysRole.ROLE_ADMIN, SysRole.ROLE_USER}) public String execute() throws Exception { return SUCCESS; } 到此,大功告成。还需要简单的配置一下拦截器,这个就不写了。还要注意,需要有一个全局结果页面,用以展示“未经授权”。我的BaseActionSupport.UNAUTHORIZED是转跳到403.jsp页面的。 |
|
来自: CevenCheng > 《权限管理》