1.对所有的Action进行拦截 添加拦截器
2.对JSP进行拦截 用Filter 这样可以保证页面的安全。。。
eg:
1. package com.work.qxgl.login;
2.
3. import java.util.List;
4. import java.util.Map;
5.
6. import javax.servlet.http.HttpServletRequest;
7.
8. import org.apache.commons.logging.Log;
9. import org.apache.commons.logging.LogFactory;
10. import org.apache.struts2.StrutsConstants;
11. import org.apache.struts2.config.DefaultSettings;
12.
13. import com.opensymphony.xwork2.Action;
14. import com.opensymphony.xwork2.ActionInvocation;
15. import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
16. import com.work.core.QxglConstants;
17. import com.work.core.spring.MyBeanUtil;
18. import com.work.qxgl.model.QxglRole;
19. import com.work.qxgl.usermodel.UserModelServiceDao;
20.
21. public class AuthorizationInterceptor extends AbstractInterceptor {
22. /**
23. *
24. */
25. private static final long serialVersionUID = 4949812834762901805L;
26. private static Log log = LogFactory.getLog(AuthorizationInterceptor.class);
27.
28.
29. @Override
30. public String intercept(ActionInvocation invocation) throws Exception {
31. // 取得请求的Action名
32. String name = invocation.getInvocationContext().getName(); // action
33. // 的名称,在xml中配置的
34. String namespace = invocation.getProxy().getNamespace(); // 获取到namespace,还能够获取到要执行的方法,class等
35.
36. if ((namespace != null) && (namespace.trim().length() > 0)) {
37. if ("/".equals(namespace.trim())) {
38. // 说明是根路径,不需要再增加反斜杠了。
39. } else {
40. namespace += "/";
41. }
42. }
43. String URL = namespace + invocation.getProxy().getActionName();
44.
45. URL += ".action";
46.
47. log.debug("actionname=" + name + "||fullActionName=" + URL);
48.
49. if (name.equals("login") || name.equals("loginAccess")) {
50. // 如果用户想登录,则使之通过
51. return invocation.invoke();
52. }
53. Map session = invocation.getInvocationContext().getSession();
54. // TODO 在这里判断用户是否已经登陆,更改此方法,和OnLineUserManager联系起来,
55. //OnLineUserManager 是线程安全的,效率上可能会比较低!所以暂时还不更改!。
56. String success = (String) session.get(QxglConstants.AUTH_SUCCESS);
57.
58. log.debug("success=" + success);
59.
60. // 如果没有登陆,那么就退出系统
61. if (success == null || !"true".equals(success)) {
62. log.debug("please login");
63. return Action.LOGIN;
64. }
65.
66. String userid = (String) session.get("userid");
67. if (userid == null || "".equals(userid)) {
68. log.error("用户id不能为空!");
69. return Action.LOGIN;
70. }
71.
72. // 如果是超级管理员,那么直接返回
73. if ("admin1111222233334444555566admin".equals(userid)) {
74. return invocation.invoke();
75. }
76.
77. UserModelServiceDao userModelServiceDao = (UserModelServiceDao) MyBeanUtil
78. .getBean("userModelServiceDao");
79. // 获取当前用户所拥有的角色
80. List<QxglRole> userRoles = userModelServiceDao.getRoles(userid);
81.
82. if (userRoles == null || userRoles.size() < 1) {
83. // 没有任何角色
84. log.warn("此用户" + userid + "没有任何角色,没有权限执行任何功能");
85. return "noPermit";
86. }
87.
88. List<QxglRole> urlRoles = userModelServiceDao.getRolesByUrl(URL);
89.
90. // 如果此URL没有赋给任何角色,说明是合法用户就可以访问
91. if (urlRoles == null || urlRoles.size() < 1) {
92. log.debug("此资源未赋给任何角色,合法用户就可以访问");
93. return invocation.invoke();
94. }
95.
96. // 根据角色来判断用户是否有权限来使用当前的URL(action)
97. boolean flag = false;// 如果有权限访问设置为true;
98. int userLen = userRoles.size();
99. int urlLen = urlRoles.size();
100. QxglRole tempUserRole = null;
101. QxglRole tempUrlRole = null;
102.
103. START:
104. for (int i = 0; i < userLen; i++) {
105. // 首先初始化
106. tempUserRole = null;
107. tempUrlRole = null;
108. tempUserRole = userRoles.get(i);
109. for (int j = 0; j < urlLen; j++) {
110. tempUrlRole = urlRoles.get(j);
111. if (tempUserRole.getId().equals(tempUrlRole.getId())) {
112. flag = true;
113. break START;
114. }
115. }
116. }
117. if (flag) {
118. log.debug("success auth");
119. return invocation.invoke();
120. } else {
121. //用户如果在主页面中输入其他的任何链接,系统将自动执行logout动作,因为在/sysmenu/top.jsp中配置了onunload事件。
122. log.warn("此用户" + userid + "没有权限执行此功能"+URL);
123. return "noPermit";
124. }
125.
126. }
127.
128.
129.
130.
131. }
在struts2的配置文件中配置
1. <package name="qxglmain" extends="struts-default" namespace="/">
2.
3. <!-- 自定义拦截器 -->
4. <interceptors>
5. <interceptor name="auth"
6. class="com.work.qxgl.login.AuthorizationInterceptor" />
7. <interceptor name="ourLogger"
8. class="com.work.core.interceptor.LoggingInterceptor" />
9. <interceptor name="ourTimer"
10. class="com.work.core.interceptor.TimerInterceptor" />
11. <!-- 自定义拦截器堆栈 -->
12. <interceptor-stack name="qxglStack">
13. <interceptor-ref name="auth" /><!-- 权限控制 -->
14. <!-- 用来查看每个action执行了多长时间,看执行效率,只所以重新编写,因为xwork的源代码的日志级别低为INFO,我们配置的日志级别为ERROR。所以看不到了 -->
15. <interceptor-ref name="ourTimer" />
16. <interceptor-ref name="ourLogger" />
17. <!--
18. <interceptor-ref name="logger" /> -->
19. <!-- 引用默认的拦截器堆栈 -->
20. <interceptor-ref name="defaultStack" />
21. </interceptor-stack>
22. </interceptors>
23.
24. <!-- 重定义默认拦截器堆栈 -->
25. <default-interceptor-ref name="qxglStack" />
26.
27. <global-results>
28. <result name="login" type="redirectAction">login</result>
29. <result name="error">/qxgl/error.jsp</result>
30. <result name="noPermit">/qxgl/noPermit.jsp</result>
31. <result name="input" type="redirectAction">login</result>
32. </global-results>
33. <!-- exception的配置必须在global-results后面 -->
34. <global-exception-mappings>
35. <exception-mapping
36. exception="java.lang.NullPointerException" result="error" />
37. <exception-mapping exception="java.lang.Exception"
38. result="error" />
39. <exception-mapping
40. exception="com.work.core.exception.StorageException" result="error" />
41. </global-exception-mappings>
42.
43. <action name="qxglmain"
44. class="com.work.qxgl.main.QxglMainAction">
45. <result>/qxgl/menutree/qxglmain.jsp</result>
46. </action>
47. <action name="sysmain"
48. class="com.work.qxgl.main.QxglMainAction" method="sysmain">
49. <result>/sysmenu/sysMain.jsp</result>
50. </action>
51. <action name="login" class="com.work.qxgl.login.LoginAction"
52. method="login">
53. <result>/login.jsp</result>
54. </action>
55. <action name="logout" class="com.work.qxgl.login.LogoutAction">
56. <result>/login.jsp</result>
57. </action>
58.
59. <action name="loginAccess" class="com.work.qxgl.login.LoginAction">
60. <result type="redirectAction">sysmain</result>
61. <result name="input" >/login.jsp</result>
62. </action>
63. <action name="listOnLineUsers" class="com.work.qxgl.login.OnLineUserAction">
64. <result>/qxgl/onlineuser/onlineuser.jsp</result>
65. </action>
66. <action name="kickUser" class="com.work.qxgl.login.OnLineUserAction"
67. method="kickUser">
68. <result type="chain">listOnLineUsers</result>
69. </action>
70. <action name="listMenu" class="com.work.qxgl.main.QxglMainAction"
71. method="listMenu">
72. <result>/sysmenu/menu.jsp</result>
73. </action>
74. </package>
缺点:
struts2的拦截器只能够控制*.action,其他的jsp文件等会被忽略,所以通过struts2的拦截器实现权限控制有一定的缺陷。
我们可以通过编写一个filter来控制其他请求的权限
1. package com.work.core.filter;
2.
3. /**
4. * wangmingjie
5. * @date 2008-8-25下午10:09:26
6. */
7. import java.io.IOException;
8.
9. import javax.servlet.Filter;
10. import javax.servlet.FilterChain;
11. import javax.servlet.FilterConfig;
12. import javax.servlet.ServletException;
13. import javax.servlet.ServletRequest;
14. import javax.servlet.ServletResponse;
15. import javax.servlet.http.HttpServletRequest;
16. import javax.servlet.http.HttpServletResponse;
17. import javax.servlet.http.HttpSession;
18.
19. import org.apache.commons.logging.Log;
20. import org.apache.commons.logging.LogFactory;
21.
22. import com.work.core.QxglConstants;
23.
24. public class AuthFilter implements Filter {
25. private static Log log = LogFactory.getLog(AuthFilter.class);
26.
27. public void init(FilterConfig filterConfig) throws ServletException {
28. if(log.isDebugEnabled()){
29. log.debug("初始化权限过滤器。");
30. }
31. }
32.
33. public void doFilter(ServletRequest servletRequest,
34. ServletResponse servletResponse, FilterChain filterChain)
35. throws IOException, ServletException {
36. /**
37. * 1,doFilter方法的第一个参数为ServletRequest对象。此对象给过滤器提供了对进入的信息(包括
38. * 表单数据、cookie和HTTP请求头)的完全访问。第二个参数为ServletResponse,通常在简单的过
39. * 滤器中忽略此参数。最后一个参数为FilterChain,此参数用来调用servlet或JSP页。
40. */
41.
42. HttpServletRequest request = (HttpServletRequest) servletRequest;
43. /**
44. * 如果处理HTTP请求,并且需要访问诸如getHeader或getCookies等在ServletRequest中
45. * 无法得到的方法,就要把此request对象构造成HttpServletRequest
46. */
47. HttpServletResponse response = (HttpServletResponse) servletResponse;
48.
49. String currentURL = request.getRequestURI(); // 取得根目录所对应的绝对路径:
50.
51. HttpSession session = request.getSession(false);
52.
53.
54. //如果jsp就验证(login.jsp除外)
55. if (currentURL.indexOf(QxglConstants.LOGIN_PAGE)==-1 && currentURL.indexOf(".jsp")>-1 ) {
56. if(log.isDebugEnabled()){
57. log.debug("对jsp文件进行权限验证。"+"请求的URL:"+currentURL);
58. }
59. // 判断当前页是否是重定向以后的登录页面页面,如果是就不做session的判断,防止出现死循环
60. if(session == null || session.getAttribute(QxglConstants.AUTH_SUCCESS) == null ){
61. response.sendRedirect(request.getContextPath()+QxglConstants.LOGIN_PAGE);
62. return ;
63. }
64. }
65. // 加入filter链继续向下执行
66. filterChain.doFilter(request, response);
67. /**
68. * 调用FilterChain对象的doFilter方法。Filter接口的doFilter方法取一个FilterChain对象作 为它
69. * 的一个参数。在调用此对象的doFilter方法时,激活下一个相关的过滤器。如果没有另
70. * 一个过滤器与servlet或JSP页面关联,则servlet或JSP页面被激活。
71. */
72. }
73.
74.
75. public void destroy() {
76.
77. }
78. }
package com.work.core;
/**
* 权限管理系统全局变量定义。
* wangmingjie
*
*/
public class QxglConstants {
public static final String CONTEXT_PATH = "/zlda";//web应用的上下文
//如果真的需要,那么编写web监听器lisenter,获取到web应用的上下文之后,自动赋值。
//需要在web.xml配置监听器
public static final String pageExtension = ".action";//使用struts2定义的action的后缀
//系统的扩展名称可以在web.xml中配置
//目前必须是false,因为acegi的权限实现的不完整。
public static final boolean USE_ACEGI = false;
public static final String AUTH_SUCCESS = "julingworksuccess";
public static final String LOGIN_PAGE = "/login.jsp";
public static final String LOG_FILE_PATH = "D:/logs";
}
在web.xml中配置权限过滤器
1. <!-- 进行权限验证 -->
2. <filter>
3. <filter-name>AuthFilter</filter-name>
4. <filter-class>
5. com.work.core.filter.AuthFilter
6. </filter-class>
7. </filter>
8. <filter-mapping>
9. <filter-name>AuthFilter</filter-name>
10. <url-pattern>/*</url-pattern>
11. </filter-mapping>