View Javadoc

1   /*
2    * $Id: RolesInterceptor.java 651946 2008-04-27 13:41:38Z apetrelli $
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
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   *  &lt;!-- START SNIPPET: example --&gt;
68   *  &lt;!-- only allows the admin and member roles --&gt;
69   *  &lt;action name=&quot;someAction&quot; class=&quot;com.examples.SomeAction&quot;&gt;
70   *      &lt;interceptor-ref name=&quot;completeStack&quot;/&gt;
71   *      &lt;interceptor-ref name=&quot;roles&quot;&gt;
72   *        &lt;param name=&quot;allowedRoles&quot;&gt;admin,member&lt;/param&gt;
73   *      &lt;/interceptor-ref&gt;
74   *      &lt;result name=&quot;success&quot;&gt;good_result.ftl&lt;/result&gt;
75   *  &lt;/action&gt;
76   *  &lt;!-- END SNIPPET: example --&gt;
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 }