1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.apache.struts2.interceptor;
23
24 import java.util.ArrayList;
25 import java.util.Arrays;
26 import java.util.Collections;
27 import java.util.List;
28
29 import javax.servlet.http.HttpServletRequest;
30 import javax.servlet.http.HttpServletResponse;
31
32 import com.opensymphony.xwork2.ActionInvocation;
33 import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
34
35 import org.apache.struts2.ServletActionContext;
36
37 /***
38 * <!-- START SNIPPET: description --> This interceptor ensures that the action
39 * will only be executed if the user has the correct role. <!--
40 * END SNIPPET: description -->
41 *
42 * <p/> <u>Interceptor parameters:</u>
43 *
44 * <!-- START SNIPPET: parameters -->
45 *
46 * <ul>
47 *
48 * <li>allowedRoles - a comma-separated list of roles to allow</li>
49 *
50 * <li>disallowedRoles - a comma-separated list of roles to disallow</li>
51 *
52 * </ul>
53 *
54 * <!-- END SNIPPET: parameters -->
55 *
56 * <!-- START SNIPPET: extending --> There are two extensions to the
57 * existing interceptor:
58 * <ul>
59 * <li>isAllowed(HttpServletRequest,Object) - whether or not to allow
60 * the passed action execution with this request</li>
61 * <li>handleRejection(ActionInvocation) - handles an unauthorized
62 * request.</li>
63 * </ul>
64 * <!-- END SNIPPET: extending -->
65 *
66 * <pre>
67 * <!-- START SNIPPET: example -->
68 * <!-- only allows the admin and member roles -->
69 * <action name="someAction" class="com.examples.SomeAction">
70 * <interceptor-ref name="completeStack"/>
71 * <interceptor-ref name="roles">
72 * <param name="allowedRoles">admin,member</param>
73 * </interceptor-ref>
74 * <result name="success">good_result.ftl</result>
75 * </action>
76 * <!-- END SNIPPET: example -->
77 * </pre>
78 */
79 public class RolesInterceptor extends AbstractInterceptor {
80
81 private List<String> allowedRoles = new ArrayList<String>();
82 private List<String> disallowedRoles = new ArrayList<String>();
83
84 public void setAllowedRoles(String roles) {
85 this.allowedRoles = stringToList(roles);
86 }
87
88 public void setDisallowedRoles(String roles) {
89 this.disallowedRoles = stringToList(roles);
90 }
91
92 public String intercept(ActionInvocation invocation) throws Exception {
93 HttpServletRequest request = ServletActionContext.getRequest();
94 HttpServletResponse response = ServletActionContext.getResponse();
95 String result = null;
96 if (!isAllowed(request, invocation.getAction())) {
97 result = handleRejection(invocation, response);
98 } else {
99 result = invocation.invoke();
100 }
101 return result;
102 }
103
104 /***
105 * Splits a string into a List
106 */
107 protected List<String> stringToList(String val) {
108 if (val != null) {
109 String[] list = val.split("[ ]*,[ ]*");
110 return Arrays.asList(list);
111 } else {
112 return Collections.EMPTY_LIST;
113 }
114 }
115
116 /***
117 * Determines if the request should be allowed for the action
118 *
119 * @param request The request
120 * @param action The action object
121 * @return True if allowed, false otherwise
122 */
123 protected boolean isAllowed(HttpServletRequest request, Object action) {
124 if (allowedRoles.size() > 0) {
125 boolean result = false;
126 for (String role : allowedRoles) {
127 if (request.isUserInRole(role)) {
128 result = true;
129 }
130 }
131 return result;
132 } else if (disallowedRoles.size() > 0) {
133 for (String role : disallowedRoles) {
134 if (request.isUserInRole(role)) {
135 return false;
136 }
137 }
138 }
139 return true;
140 }
141
142 /***
143 * Handles a rejection by sending a 403 HTTP error
144 *
145 * @param invocation The invocation
146 * @return The result code
147 * @throws Exception
148 */
149 protected String handleRejection(ActionInvocation invocation,
150 HttpServletResponse response)
151 throws Exception {
152 response.sendError(HttpServletResponse.SC_FORBIDDEN);
153 return null;
154 }
155 }