转载请注明出处:http://blog.csdn.net/wklken/archive/2011/04/23/6342985.aspx
在使用struts2框架开发一个办公OA系统时候,需要使用到权限控制
除了判定是否登陆之外,还必须对每个action的访问实现权限控制,因为如果用户登陆成功了,而且以前拥有某个权限的访问,记录下访问的action,而现在没有权限了,也能直接在地址栏输入action路径直接访问,这将使权限这一模块毫无用处。
因为没有用到命名空间,这里对于涉及命名空间的没有控制
解决思路:【先看这个,懂了以下代码就明白了】
我们知道struts2的拦截器可以很方便实现对action的访问拦截,先行判断然后再决定是否能够访问。我的实现方法是:
1.左侧菜单的树形每一列对应一个子模块,也对应一个权限控制ID,若是用户拥有权限,显示,没有,不显示
2.配置一个xml文件,包含所有权限ID以及其对应的子模块的action,由于某些模块可能使用相同的action,将存在同名的action配置【待会实现注意】
3.定义一个servlet,在web.xml中配置其启动优先,服务器启动加载
4.在servlet中,启动是使用插件读入xml文件内容,转化为一个hashmap,键值为action的name属性,value为对应权限id的组合字符串,以空格隔开
5.hashmap放入application
6.在struts.xml中定义拦截器的package,定义一个拦截器,配置拦截器栈,其他需要使用到拦截器的package在配置是使用extends这个拦截器package
7.用户登陆后从数据库查询权限,转为一个hashmap,权限id为键值【为了查询方便】,放入session
8.实现拦截器,从session中取用户权限,从application中取action映射权限ID的map,从拦截器的invocation中取此次访问的action在配置文件中的actionName
先判定是否登陆,否,转login.jsp
是,判定用户是否有访问此action的权限,否,跳到消息页,是,通过
实现步骤:
1.关于左侧菜单的显示,是标签和js等的内容,不再解释,这里主要是地址栏非法访问的控制
2.配置xml文件 authority.xml,配置对应的权限id和其可使用的action【name属性为在struts.xml中配置action的name属性】
- <?xml version="1.0" encoding="UTF-8"?>
-
- <total>
-
-
- <authority id="18">
- <action name="addRecord"/>
- <action name="deleteRecord"/>
- <action name="updateRecord"/>
- <action name="getAllRecordList"/>
- <action name="getRecordContent"/>
- </authority>
-
- </total>
3.定义servlet,启动加载配置
web.xml中
- <servlet>
- <servlet-name>InitBuild</servlet-name>
- <servlet-class>interceptor.InitBuild</servlet-class>
- <load-on-startup>1</load-on-startup>
- </servlet>
对应servlet【省略package import等】
- public class InitBuild extends HttpServlet {
-
- public void init() throws ServletException {
- try {
- String path = this.getServletContext().getRealPath("/");
- this.getServletContext().setAttribute("path", path);
- this.getServletContext().setAttribute("msg", "启动加载完毕");
-
- String xmlPath = path+"WEB-INF/authority.xml";
- this.getServletContext().setAttribute("xmlpath", xmlPath);
-
-
- this.getServletContext().setAttribute("authorityMap", InitXmlAuthorInfo.getAuthorityMap(xmlPath));
- } catch (Exception e) {
- e.printStackTrace();
- } }}
4.在3中调用的方法,主要读入xml文件,转为hashmap,这里是用dom4j
- import org.dom4j.Document;
- import org.dom4j.Element;
- import org.dom4j.io.SAXReader;
- public class InitXmlAuthorInfo {
-
-
- private static Document getDom(String xmlPath) {
- try {
- SAXReader reader = new SAXReader();
- Document document = null;
-
- document = reader.read(new File(xmlPath));
- return document;
- } catch (Exception e) {
- e.printStackTrace();
- return null;
- }
- }
-
- public static HashMap<String,String> getAuthorityMap(String xmlPath)
- {
- HashMap<String,String> authorityMap = new HashMap<String,String>();
- Document document = getDom(xmlPath);
- Element rootElm = document.getRootElement();
- for (Iterator i = rootElm.elementIterator(); i.hasNext();) {
- Element element = (Element) i.next();
-
- String id = element.attributeValue("id");
-
- List<Element> temp = element.elements();
- for (int j = 0,length = temp.size();j<length; j++) {
- String actionName = temp.get(j).attribute("name").getText();
-
-
- if(authorityMap.containsKey(actionName))
- {
- authorityMap.put(actionName,authorityMap.get(actionName)+" "+id);
- }else{
- authorityMap.put(actionName,id);
- }
- }
- }
- return authorityMap;
- }
- }
5.配置拦截器和拦截器栈 struts.xml中配置
-
- <package name="authorityCheck" extends="struts-default">
- <interceptors>
-
- <interceptor name="authority" class="interceptor.AuthorizationInterceptor"/>
-
-
- <interceptor-stack name="authorityStack">
-
- <interceptor-ref name="defaultStack"></interceptor-ref>
- <interceptor-ref name="authority"></interceptor-ref>
- </interceptor-stack>
- </interceptors>
-
-
- <default-interceptor-ref name="authorityStack"></default-interceptor-ref>
-
-
-
- <global-results>
-
- <result name="login">/login.jsp</result>
-
- <result name="authorityDeny">/authorityMsg.jsp</result>
- </global-results>
- </package>
6.实现拦截器
- package interceptor;
-
- import java.util.Iterator;
- import java.util.Map;
-
- import com.opensymphony.xwork2.Action;
- import com.opensymphony.xwork2.ActionInvocation;
- import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
-
- public class AuthorizationInterceptor extends AbstractInterceptor {
-
- @Override
- public String intercept(ActionInvocation invocation) throws Exception {
-
- Map session = invocation.getInvocationContext().getSession();
-
-
- if(session.get("UserID") == null)
- {
- System.out.println("AUTHOR ERROR:未登录");
- return Action.LOGIN;
- }
-
- Map application = invocation.getInvocationContext().getApplication();
-
-
- Map globalAuthorityMap = (Map)application.get("authorityMap");
-
-
-
-
-
-
-
-
- Map userAuthorityMap = (Map)session.get("AuthMap");
-
-
- String actionName = invocation.getProxy().getActionName();
-
- String authorStr = (String)globalAuthorityMap.get(actionName);
-
-
-
- String[] authorList = authorStr.split(" ");
-
- for (int i = 0; i < authorList.length; i++) {
- if(userAuthorityMap.containsKey(authorList[i]))
- {
- return invocation.invoke();
- }
- }
- session.put("authorityMag", "对不起,您没有权限进行此操作");
- return "authorityDeny";
- }
-
- }
7.其他package的配置
注,登陆注销的action不需要
- <package name="record" extends="authorityCheck">
-
- <action name="getRecordContent" class="com.oa.team4.action.RecordAction"
- method="getRecordContent">
- <result name="success">/record/edit_record.jsp</result>
- </action>
-
- </package>