And a small fix (forgot to get the password from the callback data as well). Supersedes the previous patch.
Regards, Marcel Ammerlaan. On Jan 5, 2008 3:55 AM, Marcel Ammerlaan <[EMAIL PROTECTED]> wrote: > Hi, > > I've attached a patch to issue WSS-68 that includes the following: > 1) Allow for a PasswordNone option to configure passwordless > UsernameTokens > 2) Allow Password callbacks to also provide the username > > For this some (small) changes and cleanups were needed, as it is now > permissable to return 'null' passwords. Checks related > to this have been removed (which I think is not a real problem as code > depending on passwords not being null, will now get a NullPointerException > instead). > Also, it is allowable to always set the identity in the callback handler, > but I've only tested it for the UsernameToken. Extending it to work for > Signatures as > well seems logical, but I'd first like to hear feedback on a smaller scale > change before making more changes. > > I've attached the patch to this mail as well. > > Regards, > > Marcel Ammerlaan. > >
Index: org/apache/ws/security/processor/DerivedKeyTokenProcessor.java =================================================================== --- org/apache/ws/security/processor/DerivedKeyTokenProcessor.java (revision 609085) +++ org/apache/ws/security/processor/DerivedKeyTokenProcessor.java (working copy) @@ -33,8 +33,6 @@ import org.apache.ws.security.util.Base64; import org.w3c.dom.Element; -import sun.security.x509.KeyIdentifier; - import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.UnsupportedCallbackException; Index: org/apache/ws/security/message/token/UsernameToken.java =================================================================== --- org/apache/ws/security/message/token/UsernameToken.java (revision 609085) +++ org/apache/ws/security/message/token/UsernameToken.java (working copy) @@ -45,6 +45,7 @@ * UsernameToken according to WS Security specifications, UsernameToken profile. * * Enhanced to support digest password type for username token signature + * Enhanced to support passwordless usernametokens as allowed by spec. * * @author Davanum Srinivas ([EMAIL PROTECTED]) * @author Werner Dittmann ([EMAIL PROTECTED]) @@ -168,7 +169,8 @@ * @param pwType * the required password encoding, either * [EMAIL PROTECTED] WSConstants#PASSWORD_DIGEST} or - * [EMAIL PROTECTED] WSConstants#PASSWORD_TEXT} or <code>null</code> if no + * [EMAIL PROTECTED] WSConstants#PASSWORD_TEXT} or + * [EMAIL PROTECTED] WSConstants#PASSWORD_NONE} <code>null</code> if no * password required */ public UsernameToken(boolean milliseconds, Document doc, String pwType) { @@ -399,8 +401,14 @@ */ public void setPassword(String pwd) { if (pwd == null) { - throw new IllegalArgumentException("pwd == null"); + if(this.passwordType != null) { + throw new IllegalArgumentException("pwd == null but a password is needed"); + } else { + // Ignore setting the password. + return; + } } + raw_password = pwd; // enhancement by Alberto coletti Text node = getFirstNode(this.elementPassword); try { Index: org/apache/ws/security/message/WSSecUsernameToken.java =================================================================== --- org/apache/ws/security/message/WSSecUsernameToken.java (revision 609085) +++ org/apache/ws/security/message/WSSecUsernameToken.java (working copy) @@ -63,14 +63,10 @@ * contains the password type. Only allowed values are * [EMAIL PROTECTED] WSConstants#PASSWORD_DIGEST} and * [EMAIL PROTECTED] WSConstants#PASSWORD_TEXT}. + * or null when no password is needed. */ public void setPasswordType(String pwType) { - if (pwType == null) { - passwordType = WSConstants.PASSWORD_DIGEST; - } else if (pwType.equals(WSConstants.PASSWORD_DIGEST) - || pwType.equals(WSConstants.PASSWORD_TEXT)) { - passwordType = pwType; - } + this.passwordType = pwType; } /** Index: org/apache/ws/security/WSConstants.java =================================================================== --- org/apache/ws/security/WSConstants.java (revision 609085) +++ org/apache/ws/security/WSConstants.java (working copy) @@ -177,6 +177,15 @@ * The password type URI used in the username token */ public static final String PASSWORD_TEXT = USERNAMETOKEN_NS + "#PasswordText"; + + /** + * Sets the [EMAIL PROTECTED] org.apache.ws.security.message.WSSAddUsernameToken#build(Document, String, String) UserNameToken} + * method to send _no_ password related information. + * <p/> + * This is a required method as defined by WS Specification, Username token profile as passwords are optional. + * Also see the WS-I documentation for scenario's using this feature in a trust environment. + */ + public static final String PW_NONE = "PasswordNone"; /** * Sets the [EMAIL PROTECTED] org.apache.ws.security.message.WSEncryptBody#build(Document, Crypto) encryption} Index: org/apache/ws/security/WSPasswordCallback.java =================================================================== --- org/apache/ws/security/WSPasswordCallback.java (revision 609085) +++ org/apache/ws/security/WSPasswordCallback.java (working copy) @@ -75,7 +75,7 @@ public final static int SECURITY_CONTEXT_TOKEN = 6; public final static int CUSTOM_TOKEN = 7; public final static int ENCRYPTED_KEY_TOKEN = 8; - + private String identifier; private String password; private byte[] key; @@ -114,6 +114,19 @@ public String getIdentifer() { return identifier; } + + /** + * Extended callback interface allows for setting the username as well. + * Callback functions can change the identifier, this is intended in the usernametoken scenario + * where the usernametoken denotes the identity, but a fixed identity for signing is used + * The initial value is that from the configuration file. If this method is not called, the + * configured identity is used. + * + * @param ident The identity. + */ + public void setIdentifier(String ident) { + this.identifier = ident; + } /** * Set the password. Index: org/apache/ws/security/handler/WSHandler.java =================================================================== --- org/apache/ws/security/handler/WSHandler.java (revision 609085) +++ org/apache/ws/security/handler/WSHandler.java (working copy) @@ -51,10 +51,11 @@ /** * Extracted from WSDoAllReceiver and WSDoAllSender + * Extended to all passwordless UsernameTokens and configurable identities. * - * * @author Davanum Srinivas ([EMAIL PROTECTED]). * @author Werner Dittmann ([EMAIL PROTECTED]). + * @author Marcel Ammerlaan ([EMAIL PROTECTED]). */ public abstract class WSHandler { public static String DONE = "done"; @@ -430,11 +431,17 @@ Object mc = reqData.getMsgContext(); String type = getString(WSHandlerConstants.PASSWORD_TYPE, mc); - reqData.setPwType(type); if (type != null) { - reqData.setPwType(type.equals(WSConstants.PW_TEXT) - ? WSConstants.PASSWORD_TEXT - : WSConstants.PASSWORD_DIGEST); + if(WSConstants.PW_TEXT.equals(type)) { + reqData.setPwType(WSConstants.PASSWORD_TEXT); + } else if(WSConstants.PW_DIGEST.equals(type)) { + reqData.setPwType(WSConstants.PASSWORD_DIGEST); + } else if(WSConstants.PW_NONE.equals(type)) { + // No password requested. + reqData.setPwType(null); + } else { + throw new WSSecurityException("Unknown password type encoding: " + type); + } } String add = getString(WSHandlerConstants.ADD_UT_ELEMENTS, mc); @@ -604,8 +611,7 @@ throw new WSSecurityException( "WSHandler: illegal timestampStrict parameter"); } - - + /** * Get a password to construct a UsernameToken or sign a message. * <p/> @@ -620,25 +626,19 @@ WSPasswordCallback pwCb = null; String password = null; CallbackHandler cbHandler = null; - String err = "provided null or empty password"; - Object mc = reqData.getMsgContext(); + String err = "provided null or empty password"; + Object mc = reqData.getMsgContext(); String callback = getString(clsProp, mc); if (callback != null) { // we have a password callback class pwCb = readPwViaCallbackClass(callback, username, doAction, reqData); - if ((pwCb.getPassword() == null) && (pwCb.getKey() == null)) { - throw new WSSecurityException("WSHandler: password callback class " - +err); - } - } else if ((cbHandler = (CallbackHandler) getProperty(mc, refProp)) - != null) { + // Null passwords are not always a problem: if the callback was called to provide a username instead. + } else if ((cbHandler = (CallbackHandler) getProperty(mc, refProp)) != null) { pwCb = performCallback(cbHandler, username, doAction); - if ((pwCb.getPassword() == null) && (pwCb.getKey() == null)) { - throw new WSSecurityException("WSHandler: password callback " - +err); - } } else if ((password = getPassword(mc)) == null) { - throw new WSSecurityException("WSHandler: application "+err); + // TODO: hmm. does this also need changed for username processing? + throw new WSSecurityException("WSHandler: application " + err); } else { + // TODO: hmm. does this also need changed for username processing? setPassword(mc, null); pwCb = new WSPasswordCallback("", WSPasswordCallback.UNKNOWN); pwCb.setPassword(password); Index: org/apache/ws/security/action/UsernameTokenAction.java =================================================================== --- org/apache/ws/security/action/UsernameTokenAction.java (revision 609085) +++ org/apache/ws/security/action/UsernameTokenAction.java (working copy) @@ -17,6 +17,8 @@ package org.apache.ws.security.action; +import org.apache.ws.security.WSConstants; +import org.apache.ws.security.WSPasswordCallback; import org.apache.ws.security.WSSecurityException; import org.apache.ws.security.handler.RequestData; import org.apache.ws.security.handler.WSHandler; @@ -27,18 +29,20 @@ public class UsernameTokenAction implements Action { public void execute(WSHandler handler, int actionToDo, Document doc, RequestData reqData) throws WSSecurityException { - String password; - password = - handler.getPassword(reqData.getUsername(), + + // Always call the callback for the username. We mis-use the configured password callback class and callback methods for this. + String providedUsername = reqData.getUsername(); + WSPasswordCallback callbackData = handler.getPassword(reqData.getUsername(), actionToDo, WSHandlerConstants.PW_CALLBACK_CLASS, - WSHandlerConstants.PW_CALLBACK_REF, reqData) - .getPassword(); + WSHandlerConstants.PW_CALLBACK_REF, reqData); + providedUsername = callbackData.getIdentifer(); + String password = callbackData.getPassword(); WSSecUsernameToken builder = new WSSecUsernameToken(); builder.setWsConfig(reqData.getWssConfig()); builder.setPasswordType(reqData.getPwType()); - builder.setUserInfo(reqData.getUsername(), password); + builder.setUserInfo(providedUsername, password); if (reqData.getUtElements() != null && reqData.getUtElements().length > 0) { for (int j = 0; j < reqData.getUtElements().length; j++) {
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]