View Javadoc

1   /* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
2    *
3    * Licensed under the Apache License, Version 2.0 (the "License");
4    * you may not use this file except in compliance with the License.
5    * You may obtain a copy of the License at
6    *
7    *     http://www.apache.org/licenses/LICENSE-2.0
8    *
9    * Unless required by applicable law or agreed to in writing, software
10   * distributed under the License is distributed on an "AS IS" BASIS,
11   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12   * See the License for the specific language governing permissions and
13   * limitations under the License.
14   */
15  
16  package org.acegisecurity.runas;
17  
18  import org.acegisecurity.Authentication;
19  import org.acegisecurity.ConfigAttribute;
20  import org.acegisecurity.ConfigAttributeDefinition;
21  import org.acegisecurity.GrantedAuthority;
22  import org.acegisecurity.GrantedAuthorityImpl;
23  import org.acegisecurity.RunAsManager;
24  
25  import org.springframework.beans.factory.InitializingBean;
26  
27  import org.springframework.util.Assert;
28  
29  import java.util.Iterator;
30  import java.util.List;
31  import java.util.Vector;
32  
33  
34  /**
35   * Basic concrete implementation of a {@link RunAsManager}.<p>Is activated if any {@link
36   * ConfigAttribute#getAttribute()} is prefixed  with <Code>RUN_AS_</code>. If found, it generates a new {@link
37   * RunAsUserToken} containing the same principal, credentials and granted authorities as the original {@link
38   * Authentication} object, along with {@link GrantedAuthorityImpl}s for each <code>RUN_AS_</code> indicated. The
39   * created <code>GrantedAuthorityImpl</code>s will be prefixed with a special prefix indicating that it is a role
40   * (default prefix value is <code>ROLE_</code>), and then the remainder of the <code>RUN_AS_</code> keyword. For
41   * example, <code>RUN_AS_FOO</code> will result in the creation of a granted authority of
42   * <code>ROLE_RUN_AS_FOO</code>.</p>
43   *  <p>The role prefix may be overriden from the default, to match that used elsewhere, for example when using an
44   * existing role database with another prefix. An empty role prefix may also be specified. Note however that there are
45   * potential issues with using an empty role prefix since different categories of  {@link
46   * org.acegisecurity.ConfigAttribute} can not be properly discerned based on the prefix, with possible consequences
47   * when performing voting and other actions. However, this option may be of some use when using preexisting role names
48   * without a prefix, and no ability exists to prefix them with a role prefix on reading them in, such as provided for
49   * example in  {@link org.acegisecurity.userdetails.jdbc.JdbcDaoImpl}.</p>
50   *
51   * @author Ben Alex
52   * @author colin sampaleanu
53   * @version $Id: RunAsManagerImpl.java 1496 2006-05-23 13:38:33Z benalex $
54   */
55  public class RunAsManagerImpl implements RunAsManager, InitializingBean {
56      //~ Instance fields ================================================================================================
57  
58      private String key;
59      private String rolePrefix = "ROLE_";
60  
61      //~ Methods ========================================================================================================
62  
63      public void afterPropertiesSet() throws Exception {
64          Assert.notNull(key, "A Key is required and should match that configured for the RunAsImplAuthenticationProvider");
65      }
66  
67      public Authentication buildRunAs(Authentication authentication, Object object, ConfigAttributeDefinition config) {
68          List newAuthorities = new Vector();
69          Iterator iter = config.getConfigAttributes();
70  
71          while (iter.hasNext()) {
72              ConfigAttribute attribute = (ConfigAttribute) iter.next();
73  
74              if (this.supports(attribute)) {
75                  GrantedAuthorityImpl extraAuthority = new GrantedAuthorityImpl(getRolePrefix()
76                          + attribute.getAttribute());
77                  newAuthorities.add(extraAuthority);
78              }
79          }
80  
81          if (newAuthorities.size() == 0) {
82              return null;
83          } else {
84              for (int i = 0; i < authentication.getAuthorities().length; i++) {
85                  newAuthorities.add(authentication.getAuthorities()[i]);
86              }
87  
88              GrantedAuthority[] resultType = {new GrantedAuthorityImpl("holder")};
89              GrantedAuthority[] newAuthoritiesAsArray = (GrantedAuthority[]) newAuthorities.toArray(resultType);
90  
91              return new RunAsUserToken(this.key, authentication.getPrincipal(), authentication.getCredentials(),
92                  newAuthoritiesAsArray, authentication.getClass());
93          }
94      }
95  
96      public String getKey() {
97          return key;
98      }
99  
100     public String getRolePrefix() {
101         return rolePrefix;
102     }
103 
104     public void setKey(String key) {
105         this.key = key;
106     }
107 
108     /**
109      * Allows the default role prefix of <code>ROLE_</code> to be overriden. May be set to an empty value,
110      * although this is usually not desireable.
111      *
112      * @param rolePrefix the new prefix
113      */
114     public void setRolePrefix(String rolePrefix) {
115         this.rolePrefix = rolePrefix;
116     }
117 
118     public boolean supports(ConfigAttribute attribute) {
119         if ((attribute.getAttribute() != null) && attribute.getAttribute().startsWith("RUN_AS_")) {
120             return true;
121         } else {
122             return false;
123         }
124     }
125 
126     /**
127      * This implementation supports any type of class, because it does not query the presented secure object.
128      *
129      * @param clazz the secure object
130      *
131      * @return alwaus <code>true</code>
132      */
133     public boolean supports(Class clazz) {
134         return true;
135     }
136 }