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 }