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.providers.dao.salt;
17  
18  import org.acegisecurity.AuthenticationServiceException;
19  
20  import org.acegisecurity.providers.dao.SaltSource;
21  
22  import org.acegisecurity.userdetails.UserDetails;
23  
24  import org.springframework.beans.factory.InitializingBean;
25  
26  import java.lang.reflect.Method;
27  
28  
29  /**
30   * Obtains a salt from a specified property of the {@link org.acegisecurity.userdetails.User} object.<P>This allows
31   * you to subclass <code>User</code> and provide an additional bean getter for a salt. You should use a synthetic
32   * value that does not change, such as a database primary key.  Do not use <code>username</code> if it is likely to
33   * change.</p>
34   *
35   * @author Ben Alex
36   * @version $Id: ReflectionSaltSource.java 1519 2006-05-29 15:06:32Z benalex $
37   */
38  public class ReflectionSaltSource implements SaltSource, InitializingBean {
39      //~ Instance fields ================================================================================================
40  
41      private String userPropertyToUse;
42  
43      //~ Methods ========================================================================================================
44  
45      public void afterPropertiesSet() throws Exception {
46          if ((this.getUserPropertyToUse() == null) || "".equals(this.getUserPropertyToUse())) {
47              throw new IllegalArgumentException("A userPropertyToUse must be set");
48          }
49      }
50  
51      /**
52       * Performs reflection on the passed <code>User</code> to obtain the salt.<P>The property identified by
53       * <code>userPropertyToUse</code> must be available from the passed <code>User</code> object. If it is not
54       * available, an {@link AuthenticationServiceException} will be thrown.</p>
55       *
56       * @param user which contains the method identified by <code>userPropertyToUse</code>
57       *
58       * @return the result of invoking <code>user.userPropertyToUse()</code>
59       *
60       * @throws AuthenticationServiceException if reflection fails
61       */
62      public Object getSalt(UserDetails user) {
63          try {
64              Method reflectionMethod = user.getClass().getMethod(this.userPropertyToUse, new Class[] {});
65  
66              return reflectionMethod.invoke(user, new Object[] {});
67          } catch (Exception exception) {
68              throw new AuthenticationServiceException(exception.getMessage(), exception);
69          }
70      }
71  
72      public String getUserPropertyToUse() {
73          return userPropertyToUse;
74      }
75  
76      /**
77       * The method name to call to obtain the salt. If your <code>UserDetails</code> contains a
78       * <code>UserDetails.getSalt()</code> method, you should set this property to <code>getSalt</code>.
79       *
80       * @param userPropertyToUse the name of the <b>getter</b> to call to obtain the salt from the
81       *        <code>UserDetails</code>
82       */
83      public void setUserPropertyToUse(String userPropertyToUse) {
84          this.userPropertyToUse = userPropertyToUse;
85      }
86  }