View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements. See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership. The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License. You may obtain a copy of the License at
9    *
10   * http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied. See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.ws.security;
20  
21  import java.io.IOException;
22  import java.lang.reflect.Method;
23  
24  import javax.security.auth.callback.Callback;
25  import javax.security.auth.callback.CallbackHandler;
26  import javax.security.auth.callback.NameCallback;
27  import javax.security.auth.callback.PasswordCallback;
28  import javax.security.auth.callback.UnsupportedCallbackException;
29  
30  public class NamePasswordCallbackHandler implements CallbackHandler {  
31  
32      private static org.apache.commons.logging.Log log = 
33          org.apache.commons.logging.LogFactory.getLog(NamePasswordCallbackHandler.class);
34      
35      private static final String PASSWORD_CALLBACK_NAME = "setObject";
36      private static final Class<?>[] PASSWORD_CALLBACK_TYPES = 
37          new Class<?>[]{Object.class, char[].class, String.class};
38      
39      private String username;  
40      private String password;  
41      
42      private String passwordCallbackName;
43      
44      public NamePasswordCallbackHandler(String username, String password) {  
45          this(username, password, null);  
46      }  
47       
48      public NamePasswordCallbackHandler(String username, String password, String passwordCallbackName) {  
49          this.username = username;  
50          this.password = password;
51          this.passwordCallbackName = passwordCallbackName;
52      }  
53  
54      public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {  
55          for (int i = 0; i < callbacks.length; i++) {  
56              Callback callback = callbacks[i];
57              if (handleCallback(callback)) {
58                  continue;
59              } else if (callback instanceof NameCallback) {  
60                  ((NameCallback) callback).setName(username);  
61              } else if (callback instanceof PasswordCallback) {  
62                  PasswordCallback pwCallback = (PasswordCallback) callback;  
63                  pwCallback.setPassword(password.toCharArray());
64              } else if (!invokePasswordCallback(callback)) {
65                  log.error("Unsupported callback type " + callbacks[i].getClass().getName());
66                  throw new UnsupportedCallbackException(callbacks[i], "Unsupported callback type " + callbacks[i].getClass().getName());  
67              }  
68          }  
69      }      
70      
71      protected boolean handleCallback(Callback callback) {
72          return false;
73      }
74      
75      /*
76       * This method is called from the handle(Callback[]) method when the specified callback 
77       * did not match any of the known callback classes. It looks for the callback method 
78       * having the specified method name with one of the supported parameter types.
79       * If found, it invokes the callback method on the object and returns true. 
80       * If not, it returns false.
81       */
82      private boolean invokePasswordCallback(Callback callback) {
83          String cbname = passwordCallbackName == null
84                          ? PASSWORD_CALLBACK_NAME : passwordCallbackName;
85          for (Class<?> arg : PASSWORD_CALLBACK_TYPES) {
86              try {
87                  Method method = callback.getClass().getMethod(cbname, arg);
88                  method.invoke(callback, arg == String.class ? password : password.toCharArray());
89                  return true;
90              } catch (Exception e) {
91                  // ignore and continue
92                  log.warn(e.toString());
93              }
94          }
95          return false;
96      }
97   
98  }
99