View Javadoc

1   /*
2    * Copyright 2008 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.springframework.ws.soap.security.wss4j.callback;
18  
19  import java.io.IOException;
20  import javax.security.auth.callback.Callback;
21  import javax.security.auth.callback.UnsupportedCallbackException;
22  
23  import org.apache.ws.security.WSPasswordCallback;
24  
25  import org.springframework.ws.soap.security.callback.AbstractCallbackHandler;
26  import org.springframework.ws.soap.security.callback.CleanupCallback;
27  
28  /**
29   * Abstract base class for {@link javax.security.auth.callback.CallbackHandler} implementations that handle {@link
30   * WSPasswordCallback} callbacks.
31   *
32   * @author Arjen Poutsma
33   * @since 1.5.0
34   */
35  public abstract class AbstractWsPasswordCallbackHandler extends AbstractCallbackHandler {
36  
37      /**
38       * Handles {@link WSPasswordCallback} callbacks. Inspects the callback {@link WSPasswordCallback#getUsage() usage}
39       * code, and calls the various <code>handle*</code> template methods.
40       *
41       * @param callback the callback
42       * @throws IOException                  in case of I/O errors
43       * @throws UnsupportedCallbackException when the callback is not supported
44       */
45      protected final void handleInternal(Callback callback) throws IOException, UnsupportedCallbackException {
46          if (callback instanceof WSPasswordCallback) {
47              WSPasswordCallback passwordCallback = (WSPasswordCallback) callback;
48              switch (passwordCallback.getUsage()) {
49                  case WSPasswordCallback.DECRYPT:
50                      handleDecrypt(passwordCallback);
51                      break;
52                  case WSPasswordCallback.USERNAME_TOKEN:
53                      handleUsernameToken(passwordCallback);
54                      break;
55                  case WSPasswordCallback.SIGNATURE:
56                      handleSignature(passwordCallback);
57                      break;
58                  case WSPasswordCallback.KEY_NAME:
59                      handleKeyName(passwordCallback);
60                      break;
61                  case WSPasswordCallback.USERNAME_TOKEN_UNKNOWN:
62                      handleUsernameTokenUnknown(passwordCallback);
63                      break;
64                  case WSPasswordCallback.SECURITY_CONTEXT_TOKEN:
65                      handleSecurityContextToken(passwordCallback);
66                      break;
67                  case WSPasswordCallback.CUSTOM_TOKEN:
68                      handleCustomToken(passwordCallback);
69                      break;
70                  case WSPasswordCallback.ENCRYPTED_KEY_TOKEN:
71                      handleEncryptedKeyToken(callback);
72                      break;
73                  default:
74                      throw new UnsupportedCallbackException(callback,
75                              "Unknown usage [" + passwordCallback.getUsage() + "]");
76              }
77          }
78          else if (callback instanceof CleanupCallback) {
79              handleCleanup((CleanupCallback) callback);
80          }
81          else if (callback instanceof UsernameTokenPrincipalCallback) {
82              handleUsernameTokenPrincipal((UsernameTokenPrincipalCallback) callback);
83          }
84          else {
85              throw new UnsupportedCallbackException(callback);
86          }
87      }
88  
89      /**
90       * Invoked when the callback has a {@link WSPasswordCallback#DECRYPT} usage.
91       * <p/>
92       * This method is invoked when WSS4J needs a password to get the private key of the {@link
93       * WSPasswordCallback#getIdentifer() identifier} (username) from the keystore. WSS4J uses this private key to
94       * decrypt the session (symmetric) key. Because the encryption method uses the public key to encrypt the session key
95       * it needs no password (a public key is usually not protected by a password).
96       * <p/>
97       * Default implementation throws an {@link UnsupportedCallbackException}.
98       */
99      protected void handleDecrypt(WSPasswordCallback callback) throws IOException, UnsupportedCallbackException {
100         throw new UnsupportedCallbackException(callback);
101     }
102 
103     /**
104      * Invoked when the callback has a {@link WSPasswordCallback#USERNAME_TOKEN} usage.
105      * <p/>
106      * This method is invoked when WSS4J needs the password to fill in or to verify a UsernameToken.
107      * <p/>
108      * Default implementation throws an {@link UnsupportedCallbackException}.
109      */
110     protected void handleUsernameToken(WSPasswordCallback callback) throws IOException, UnsupportedCallbackException {
111         throw new UnsupportedCallbackException(callback);
112     }
113 
114     /**
115      * Invoked when the callback has a {@link WSPasswordCallback#SIGNATURE} usage.
116      * <p/>
117      * This method is invoked when WSS4J needs the password to get the private key of the {@link
118      * WSPasswordCallback#getIdentifer() identifier} (username) from the keystore. WSS4J uses this private key to
119      * produce a signature. The signature verfication uses the public key to verfiy the signature.
120      * <p/>
121      * Default implementation throws an {@link UnsupportedCallbackException}.
122      */
123     protected void handleSignature(WSPasswordCallback callback) throws IOException, UnsupportedCallbackException {
124         throw new UnsupportedCallbackException(callback);
125     }
126 
127     /**
128      * Invoked when the callback has a {@link WSPasswordCallback#KEY_NAME} usage.
129      * <p/>
130      * This method is invoked when WSS4J needs the key associated with the {@link WSPasswordCallback#getIdentifer()
131      * identifier}. WSS4J uses this key to encrypt or decrypt parts of the SOAP request. Note, the key must match the
132      * symmetric encryption/decryption algorithm specified (refer to {@link org.apache.ws.security.handler.WSHandlerConstants#ENC_SYM_ALGO}).
133      * <p/>
134      * Default implementation throws an {@link UnsupportedCallbackException}.
135      */
136     protected void handleKeyName(WSPasswordCallback callback) throws IOException, UnsupportedCallbackException {
137         throw new UnsupportedCallbackException(callback);
138     }
139 
140     /**
141      * Invoked when the callback has a {@link WSPasswordCallback#USERNAME_TOKEN_UNKNOWN} usage.
142      * <p/>
143      * This method is invoked for a not specified password type or a plain text password type. Only the {@link
144      * WSPasswordCallback#getPassword() password} is set. The callback class now may check if the username and password
145      * match. If they don't match, the subclass should throw an exception.
146      * <p/>
147      * Default implementation throws an {@link UnsupportedCallbackException}.
148      */
149     protected void handleUsernameTokenUnknown(WSPasswordCallback callback)
150             throws IOException, UnsupportedCallbackException {
151         throw new UnsupportedCallbackException(callback);
152     }
153 
154     /**
155      * Invoked when the callback has a {@link WSPasswordCallback#SECURITY_CONTEXT_TOKEN} usage.
156      * <p/>
157      * This method is invoked when WSS4J needs the key to to be associated with a SecurityContextToken.
158      * <p/>
159      * Default implementation throws an {@link UnsupportedCallbackException}.
160      */
161     protected void handleSecurityContextToken(WSPasswordCallback callback)
162             throws IOException, UnsupportedCallbackException {
163         throw new UnsupportedCallbackException(callback);
164     }
165 
166     /**
167      * Invoked when the callback has a {@link WSPasswordCallback#CUSTOM_TOKEN} usage.
168      * <p/>
169      * Default implementation throws an {@link UnsupportedCallbackException}.
170      */
171     protected void handleCustomToken(WSPasswordCallback callback) throws IOException, UnsupportedCallbackException {
172         throw new UnsupportedCallbackException(callback);
173     }
174 
175     /**
176      * Invoked when the callback has a {@link WSPasswordCallback#ENCRYPTED_KEY_TOKEN} usage.
177      * <p/>
178      * Default implementation throws an {@link UnsupportedCallbackException}.
179      */
180     protected void handleEncryptedKeyToken(Callback callback) throws IOException, UnsupportedCallbackException {
181         throw new UnsupportedCallbackException(callback);
182     }
183 
184     /**
185      * Invoked when a {@link CleanupCallback} is passed to {@link #handle(Callback[])}.
186      * <p/>
187      * Default implementation throws an {@link UnsupportedCallbackException}.
188      */
189     protected void handleCleanup(CleanupCallback callback) throws IOException, UnsupportedCallbackException {
190         throw new UnsupportedCallbackException(callback);
191     }
192 
193     /**
194      * Invoked when a {@link UsernameTokenPrincipalCallback} is passed to {@link #handle(Callback[])}.
195      * <p/>
196      * Default implementation throws an {@link UnsupportedCallbackException}.
197      */
198     protected void handleUsernameTokenPrincipal(UsernameTokenPrincipalCallback callback)
199             throws IOException, UnsupportedCallbackException {
200         throw new UnsupportedCallbackException(callback);
201     }
202 }