继上篇《struts2的CRUD中的权限控制初探 》文章后,我们来实现具体的代码实现,在struts2中我们可以自定义拦截器。
心中谨记基于接口编程的指导,考虑到我们的CRUD操作涉及到load,store,remove,list四个方法,而且要记录操作者的角色,我们提取了接口IRoleAndCRUD,内容如下:
/** */
/**
* 描述: CRUD操作接口,用于struts2拦截器实现权限控制
*
* @author Stone yang 创建日期:2007-5-21
* @version pattern Study 技术支持: <a
*
*/
public
interface
IRoleAndCRUD
...
{
public String load();
public String store();
public String remove();
public void setRole(String role);
public String list();
} 下面我们就实现自己的权限拦截器,继承于实现了拦截器接口Interceptor的抽象类AbstractInterceptor,主要是实现intercept方法,该方法参数是ActionInvocation(action调用者?)可以通过ActionInvocation获取当前action相关信息,和webcontext相关信息,为around advice提供了可能,主要实现可以如下:
/** */ /**
* 描述:权限拦截器
*
* @author Stone yang 创建日期:2007-5-21
* @version pattern Study 技术支持: <a
*
*/
public
class
AuthorizationInterceptor
extends
AbstractInterceptor
...
{
private static final Logger log = Logger
.getLogger(AuthorizationInterceptor.class);
protected static Map<String, String> roleMethodMap = new HashMap<String, String>();
static ...{
if (roleMethodMap.size() <= 0) ...{
roleMethodMap.put("list", "view");
roleMethodMap.put("store", "edit");
roleMethodMap.put("remove", "remove");
}
}
@Override
public String intercept(ActionInvocation ai) throws Exception ...{
Map session = ai.getInvocationContext().getSession();
String role = (String) session.get("ROLE");
if (null == role) ...{
Object action = ai.getAction();
if (action instanceof IRoleAndCRUD) ...{
IRoleAndCRUD crudAction = (IRoleAndCRUD) action;
String methodName = ai.getProxy().getActionName();
if (role.equals(roleMethodMap.get(methodName))) ...{ //session中存储的角色和调用方法对应的权限一致
crudAction.setRole(role);
return ai.invoke();
} else ...{
return Action.LOGIN;
}
} else ...{
return Action.LOGIN;
}
} else ...{
return Action.LOGIN;
}
}
在该类中我们增加了一个静态map,来存储“角色”-“方法”的对应关系,在 intercept方法中我们根据该map判断调用方法以及当前用户角色的对应关系,如果不符合我们将转向login页面,当然登陆用户可能具有多种权限,这个map还需要根据需求进一步重构。
应用自定义拦截器也很简单,在struts.xml中定义即可,大致如下:
< package name
="admin"
extends
="struts-default"
namespace
="/admin"
>
<!-- 定义拦截器
-->
< interceptors
>
< interceptor
name
="auth"
class
="com.waimai.utils.AuthorizationInterceptor"
/>
</ interceptors
>
< action
name
="List"
class
="com.waimai.web.CaiTypeAction"
method
="list"
>
<!-- 调用拦截器
-->
< interceptor-ref
name
="auth"
/>
< result
>
listCaiType.jsp
</
result
>
</ action
>
< action
name
="Edit"
class
="com.waimai.web.CaiTypeAction"
method
="load"
>
<!-- 调用拦截器
-->
< interceptor-ref
name
="auth"
/>
< result
>
editCaiType.jsp
</
result
>
</ action
>
< action
name
="Store"
class
="com.waimai.web.CaiTypeAction"
method
="store"
>
<!-- 调用拦截器
-->
< interceptor-ref
name
="auth"
/>
< result
name
="input"
type
="dispatcher"
>
editCaiType.jsp
</
result
>
< result
type
="redirect"
>
List.action
</
result
>
</ action
>
< action
name
="Remove"
class
="com.waimai.web.CaiTypeAction"
method
="remove"
>
<!-- 调用拦截器
-->
< interceptor-ref
name
="auth"
/>
< result
type
="redirect"
>
List.action
</
result
>
</ action
>
</ package
> <interceptor-ref name ="auth"/>
这么一行,真是很不爽呀,不知道能不能给接口设置拦截器,由于自己对struts2还不是很了解,查了一些资料没有好的解决方案,如果谁有好的解决方案请告知我。感觉要做到伸缩性强,维护性强的权限系统还是需要使用acegi集成进系统....