View Javadoc

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