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]