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 }