This Blog Is Not Updated Any More.

Check out my new blog on Medium: http://facilelogin.com

Topics: Identity and Access Management, Blockchain, Ethereum, Bitcoin, Security, PSD2, GDPR



Monday, November 10, 2008

UserNameToken authentication based on Active Directory

This post explains how you can authenticate users at the service end against an Active Directory[AD] - in the CallbackHandler.

This assumes that you know how to deploy a service and configure it to accept a UserNameToken for authentication.[If not please refer this.]

If you are curious to know more on CallbackHandlers - then this may help.

To get started, follow the first part in my previous post - that is to configiure AD with the user tomcat.

Now let's get started with password CallbackHandler at the service end.

package org.apache.ws.axis2;

import java.io.IOException;

import org.apache.ws.security.WSPasswordCallback;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;

public class PWCBHandler implements CallbackHandler {

private static String SECURITY_PRINCIPAL = "cn=tomcat,cn=users,dc=home,dc=com";
private static String SECURITY_CREDENTIALS = "1qaz2wsx@";
private static String PROVIDER_URL = "ldap://192.168.1.2:389";
private static String USER_PATTERN = "cn={0},cn=Users,dc=home,dc=com";

public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {

ADAuthenticator authenticator = null;

authenticator = new ADAuthenticator(SECURITY_PRINCIPAL, SECURITY_CREDENTIALS, PROVIDER_URL,USER_PATTERN);

for (int i = 0; i < callbacks.length; i++) {

// When the server side need to authenticate the user
WSPasswordCallback pwcb = (WSPasswordCallback) callbacks[i];

// Usage value is set to USERNAME_TOKEN_UNKNOWN when the Rampart
// Engine wants the password callback handler to validate the
// username and password in the Username Token
if (pwcb.getUsage() == WSPasswordCallback.USERNAME_TOKEN_UNKNOWN) {
if (authenticator.authenticate(pwcb.getIdentifer(), pwcb.getPassword())) {
return;
} else {
throw new UnsupportedCallbackException(callbacks[i], "check failed");
}
}
}
}
}
Now lets look at the ADAuthenticator - which actually does the authentication against the AD - user base.

package org.apache.ws.axis2;

import java.text.MessageFormat;
import java.util.Hashtable;

import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;

public class ADAuthenticator {

/**
* Holds the name of the environment property for specifying the initial
* context factory to use. The value of the property should be the fully
* qualified class name of the factory class that will create an initial
* context.
*/
private static String INITIAL_CONTEXT_FACTORY = "com.sun.jndi.ldap.LdapCtxFactory";

private DirContext context = null;
private String userPattern = null;

/**
*
* @param conName
* Holds the name of the environment property for specifying the
* identity of the principal for authenticating the caller to the
* service.
* @param conPassword
* Holds the name of the environment property for specifying the
* credentials of the principal for authenticating the caller to
* the service.
* @param connectionUrl
* Holds the name of the environment property for specifying
* configuration information for the service provider to use.
* @param userPattern
* Search pattern.
*/
public ADAuthenticator(String conName, String conPassword, String connectionUrl,
String userPattern) {

Hashtable environment = null;

try {
environment = new Hashtable();
environment.put(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT_FACTORY);
environment.put(Context.SECURITY_PRINCIPAL, conName);
environment.put(Context.SECURITY_CREDENTIALS, conPassword);
environment.put(Context.PROVIDER_URL, connectionUrl);
this.userPattern = userPattern;

context = new InitialDirContext(environment);
} catch (NamingException ex) {
throw new RuntimeException();
}
}

/**
* Authenticates a given user against Active Directory user store.
*
* @param userName
* User to be authenticated.
* @param password
* Password of the user.
* @return true if authenticated.
*/
public boolean authenticate(String userName, String password) {

String dn = null;

try {
dn = MessageFormat.format(userPattern, new String[] { userName });
return this.bindAsUser(this.context, dn, (String) password);
} catch (NamingException ex) {
return false;
}

}

private boolean bindAsUser(DirContext context, String dn, String credentials)
throws NamingException {

if (credentials == null || dn == null)
return false;

context.addToEnvironment(Context.SECURITY_PRINCIPAL, dn);
context.addToEnvironment(Context.SECURITY_CREDENTIALS, credentials);

context.getAttributes("", null);

return true;
}

}

0 comments: