ws-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cohei...@apache.org
Subject svn commit: r1167072 - in /webservices/wss4j/trunk/src/main/java/org/apache/ws/security: NamePasswordCallbackHandler.java validate/JAASUsernameTokenValidator.java
Date Fri, 09 Sep 2011 10:10:46 GMT
Author: coheigea
Date: Fri Sep  9 10:10:46 2011
New Revision: 1167072

URL: http://svn.apache.org/viewvc?rev=1167072&view=rev
Log:
[WSS-313] - Support UsernameToken validation against JAAS LoginModule
 - Patch applied, thanks.

Added:
    webservices/wss4j/trunk/src/main/java/org/apache/ws/security/NamePasswordCallbackHandler.java
    webservices/wss4j/trunk/src/main/java/org/apache/ws/security/validate/JAASUsernameTokenValidator.java

Added: webservices/wss4j/trunk/src/main/java/org/apache/ws/security/NamePasswordCallbackHandler.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/NamePasswordCallbackHandler.java?rev=1167072&view=auto
==============================================================================
--- webservices/wss4j/trunk/src/main/java/org/apache/ws/security/NamePasswordCallbackHandler.java
(added)
+++ webservices/wss4j/trunk/src/main/java/org/apache/ws/security/NamePasswordCallbackHandler.java
Fri Sep  9 10:10:46 2011
@@ -0,0 +1,99 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ws.security;
+
+import java.io.IOException;
+import java.lang.reflect.Method;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+
+public class NamePasswordCallbackHandler implements CallbackHandler {  
+
+    private static org.apache.commons.logging.Log log = 
+        org.apache.commons.logging.LogFactory.getLog(NamePasswordCallbackHandler.class);
+    
+    private static final String PASSWORD_CALLBACK_NAME = "setObject";
+    private static final Class<?>[] PASSWORD_CALLBACK_TYPES = 
+        new Class<?>[]{Object.class, char[].class, String.class};
+    
+    private String username;  
+    private String password;  
+    
+    private String passwordCallbackName;
+    
+    public NamePasswordCallbackHandler(String username, String password) {  
+        this(username, password, null);  
+    }  
+     
+    public NamePasswordCallbackHandler(String username, String password, String passwordCallbackName)
{  
+        this.username = username;  
+        this.password = password;
+        this.passwordCallbackName = passwordCallbackName;
+    }  
+
+    public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException
{  
+        for (int i = 0; i < callbacks.length; i++) {  
+            Callback callback = callbacks[i];
+            if (handleCallback(callback)) {
+                continue;
+            } else if (callback instanceof NameCallback) {  
+                ((NameCallback) callback).setName(username);  
+            } else if (callback instanceof PasswordCallback) {  
+                PasswordCallback pwCallback = (PasswordCallback) callback;  
+                pwCallback.setPassword(password.toCharArray());
+            } else if (!invokePasswordCallback(callback)) {
+                log.error("Unsupported callback type " + callbacks[i].getClass().getName());
+                throw new UnsupportedCallbackException(callbacks[i], "Unsupported callback
type " + callbacks[i].getClass().getName());  
+            }  
+        }  
+    }      
+    
+    protected boolean handleCallback(Callback callback) {
+        return false;
+    }
+    
+    /*
+     * This method is called from the handle(Callback[]) method when the specified callback

+     * did not match any of the known callback classes. It looks for the callback method

+     * having the specified method name with one of the supported parameter types.
+     * If found, it invokes the callback method on the object and returns true. 
+     * If not, it returns false.
+     */
+    private boolean invokePasswordCallback(Callback callback) {
+        String cbname = passwordCallbackName == null
+                        ? PASSWORD_CALLBACK_NAME : passwordCallbackName;
+        for (Class<?> arg : PASSWORD_CALLBACK_TYPES) {
+            try {
+                Method method = callback.getClass().getMethod(cbname, arg);
+                method.invoke(callback, arg == String.class ? password : password.toCharArray());
+                return true;
+            } catch (Exception e) {
+                // ignore and continue
+                log.warn(e.toString());
+            }
+        }
+        return false;
+    }
+ 
+}
+

Added: webservices/wss4j/trunk/src/main/java/org/apache/ws/security/validate/JAASUsernameTokenValidator.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/validate/JAASUsernameTokenValidator.java?rev=1167072&view=auto
==============================================================================
--- webservices/wss4j/trunk/src/main/java/org/apache/ws/security/validate/JAASUsernameTokenValidator.java
(added)
+++ webservices/wss4j/trunk/src/main/java/org/apache/ws/security/validate/JAASUsernameTokenValidator.java
Fri Sep  9 10:10:46 2011
@@ -0,0 +1,120 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.ws.security.validate;
+
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.login.LoginContext;
+import javax.security.auth.login.LoginException;
+
+import org.apache.ws.security.NamePasswordCallbackHandler;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.handler.RequestData;
+import org.apache.ws.security.message.token.UsernameToken;
+
+
+/**
+ * This class validates a processed UsernameToken, extracted from the Credential passed to
+ * the validate method.
+ * Username/password validation is delegated to JAAS LoginContext.
+ */
+public class JAASUsernameTokenValidator implements Validator {
+    
+    private static org.apache.commons.logging.Log log = 
+        org.apache.commons.logging.LogFactory.getLog(JAASUsernameTokenValidator.class);
+    
+    private String contextName = null;
+    
+    public void setContextName(String name) {
+        contextName = name;
+    }
+    
+    public String getContextName() {
+        return contextName;
+    }
+    
+    /**
+     * Validate the credential argument. It must contain a non-null UsernameToken. A 
+     * CallbackHandler implementation is also required to be set.
+     * Validator
+     * If the password type is either digest or plaintext, it extracts a password from the

+     * CallbackHandler and then compares the passwords appropriately.
+     * 
+     * If the password is null it queries a hook to allow the user to validate UsernameTokens
+     * of this type. 
+     * 
+     * @param credential the Credential to be validated
+     * @param data the RequestData associated with the request
+     * @throws WSSecurityException on a failed validation
+     */
+    public Credential validate(Credential credential, RequestData data) throws WSSecurityException
{
+        if (credential == null || credential.getUsernametoken() == null) {
+            throw new WSSecurityException(WSSecurityException.FAILURE, "noCredential");
+        }
+        
+        String user = null;
+        String password = null;
+        
+        UsernameToken usernameToken = credential.getUsernametoken();
+        
+        user = usernameToken.getName();
+        String pwType = usernameToken.getPasswordType();
+        if (log.isDebugEnabled()) {
+            log.debug("UsernameToken user " + usernameToken.getName());
+            log.debug("UsernameToken password type " + pwType);
+        }
+        
+        if (usernameToken.isHashed()) {
+            log.warn("Authentication failed as hashed username token not supported");
+            throw new WSSecurityException(WSSecurityException.FAILED_AUTHENTICATION);
+        }
+        
+        password = usernameToken.getPassword();
+        
+        if (!WSConstants.PASSWORD_TEXT.equals(pwType)) {
+            log.warn("Password type " + pwType + " not supported");
+            throw new WSSecurityException(WSSecurityException.FAILED_AUTHENTICATION);   
    	
+        }
+        
+        if (!(user != null && user.length() > 0 && password != null &&
password.length() > 0)) {
+        	log.warn("User or password empty");
+        	throw new WSSecurityException(WSSecurityException.FAILED_AUTHENTICATION);
+        }
+        
+        try {
+            CallbackHandler handler = getCallbackHandler(user, password);  
+            LoginContext ctx = new LoginContext(getContextName(), handler);  
+            ctx.login();
+            ctx.getSubject();
+
+        } catch (LoginException ex) {
+            log.info("Authentication failed", ex);
+            throw new WSSecurityException(WSSecurityException.FAILED_AUTHENTICATION);
+        }
+        
+        return credential;
+        
+    }
+
+    protected CallbackHandler getCallbackHandler(String name, String password) {
+        return new NamePasswordCallbackHandler(name, password);
+    }
+   
+}



Mime
View raw message