Showing posts with label Active Directory. Show all posts
Showing posts with label Active Directory. Show all posts

Connecting WSO2 Identity Server 2.0 to an LDAP based user store

WSO2 Identity Server 2.0 is a free and open source identity and entitlement management server, available to download from here...

Here, we'll be discussing all the steps required to deploy WSO2 Identity Server over an LDAP user store.

First we need to setup an LDAP server.

You may download Apache Directory Studio from here and set it up.

This explains all what you need to set it up.

1. Log in to Identity Server as an admin and go to User Manager and click on 'Add External User Store'.

2. Add your LDAP server settings and click Finish.

3. Click on 'Test Connection' to test the connectivity.

4. Click on 'External Users' and then 'Search' to list users from the external user store.

5. Go back to the previous screen and click on 'External Roles'. And then 'Add New Internal Roles'. Here we are going to create a new internal role for external users.

6. Give the new role a name.

7. Select a set of permissions.

8. Search users from the external user store and add them to the role.

9. Now - we need to map the LDAP attributes the claims read by Carbon.

10.Default claim dialect for Carbon is http://wso2.org/claims. Click on it - under 'External User Store'.

11.Click on the claims you want to change and set it's attribute name properly to the LDAP attribute.

That's and we are done. Now users from the LDAP user store can login to WSO2 Identity Server.

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;
}

}

Deploying WSO2 Identity Solution over Active Directory

This post explains all the steps you need to know in deploying WSO2 Identity Solution over Microsoft Active Directory [AD].

Lets get started with setting up the AD.

I have setup my AD on Windows 2003 Server [IP:192.168.1.3] and it looks like as shown in the image below.

Let's first create an AD user, which can be used by WSO2 IS to access AD.

This user can be of any name, we'll just say 'identity'

Now we need to delegate the task, 'Read all user information' - to the user 'identity'.

[Users --> Right Click --> Delegate Control]

Done, with it. Lets create another user called 'prabath' - where this user represents any user in the AD - who can connect to the WSO2 IS and download an Information Card against his corresponding AD profile.

All set - we are done with the AD configurations - let's setup Identity Solution.

Download the latest code from the SVN repo: https://svn.wso2.org/repos/wso2/trunk/solutions/identity

Then, from the root directory (say [Identity] ) of the downloaded code.

[Make sure you have installed Maven2]

:\> mvn -Drelease clean install

The above will create a zip file distribution at [Identity]\modules\distribution\target.

Unzip the Zip file to a local folder.

You also need to download Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 5.0 from here and copy the two jar files from the extracted jce directory (local_policy.jar and US_export_policy.jar) to $JAVA_HOME/jre/lib/security.

Start WSO2 Identity Solution with [IS_INSTALLED_DIR]\bin\wso2is.bat.

Go to url : https://localhost:12443/admin and login with admin/admin [user/password] - then select 'User Stores and then 'Add new user store'.

Select LDAPRealm.

Set LDAPRealm properties. You can find the availabe AD attribute names from here.

Set Active_Directory realm as the default.

Click on 'Define Claims' and select 'Given name' and 'Email address' [Dont uncheck any claims which are already selected]

Click on 'Claim Mappings'.

Click on 'Given name' and 'Email address' and do the claim mapping appropriately.

All set, hit the url https://localhost:12443 and login with your AD user credentials.

Now you can download an Information Card from WSO2 IS, against your AD account.

Secure your services with Active Directory user credentials

This post explains how you could secure your web srevices with Microsoft Active Directory[AD] user credentials.

In other words, your services could only be accessed by a set of users who belongs to a certain group in AD.

Let's start configuring AD first.

I have setup my AD on Windows 2003 Server [IP:192.168.1.3] and it looks like as shown in the image below.

In our case we'll be deploying our services with Axis2 running on Tomcat.

You can download Axis2 WAR distribution from here and deploy it on Tomcat.

In order to authenticate users against AD, Tomcat should have access to the AD user base.

Let's first create an AD user, which can be used by Tomcat to access AD.

This user can be of any name, we'll just say 'tomcat'.

Now we need to delegate the task, 'Read all user information' - to the user 'tomcat'.

[Users --> Right Click --> Delegate Control]

Done, with it. Lets create a new group called 'facilelogin' - where the members of this group will be given access to the secured web services.

Once created, add any user to that group - I'll add the 'administrator' - so, this user will be able to access secured services.

All set - we are done with the AD configurations - let's setup Tomcat.

Find the file [CATALINA_HOME]\conf\server.xml and edit to add the following.
<!-- You need to add new configurations inside this tag -->
<Engine name="Catalina" defaultHost="localhost">

<!-- Make sure you comment out this line from your current configuration -->
<!-- Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/ -->

<!-- Add following new configuration -->
<!-- Compare the values with the Active Directory image shown above -->  
<!-- I am running my AD on 192.168.1.3 -->    
<Realm className="org.apache.catalina.realm.JNDIRealm"
connectionName="cn=tomcat,cn=users,dc=home,dc=com"
connectionPassword="1qaz2wsx@"
connectionURL="ldap://192.168.1.3:389"
userRoleName="member"
userBase="cn=Users,dc=home,dc=com"
userPattern="cn={0},cn=Users,dc=home,dc=com"
roleBase="cn=Users,dc=home,dc=com"
roleName="cn"
roleSearch="(member={0})"
roleSubtress="false"
userSubtree="true"
/>

</Engine>
Once this is done - let's open the file [CATALINA_HOME]\webapps\axis2\WEB-INF\web.xml and edit to add the following.
<web-app> 

<security-constraint> 
<web-resource-collection>
<web-resource-name>secured services 
<url-pattern>/services/* 
</web-resource-collection>
<auth-constraint> 
<!-- This is mapped to the 'facilelogin' group in AD -->
<role-name>facilelogin 
</auth-constraint> 
</security-constraint> 

<login-config> 
<auth-method>BASIC 
<realm-name>facilelogin 
</login-config> 

</web-app>
All set - let's restart Tomcat.

Let's see how we could invoke the above secured service with a web service client.

Here, the only difference is you need to setup the HTTP header attributes appropriately.

Also, in this case user credentials are not carried by the SOAP header, but the transport header.
package org.apache.ws.axis2;

import java.util.Properties;

import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
import org.apache.axis2.transport.http.HttpTransportProperties;

public class Client {

public static void main(String[] args) throws Exception {
ServiceClient client = null;
Options options = null;
OMElement response = null;
HttpTransportProperties.Authenticator authenticator = null;
Properties properties = null;

client = new ServiceClient();
options = new Options();
options.setAction("urn:getVersion");
options.setTo(new EndpointReference("http://localhost:8080/axis2/services/Version"));

authenticator = new HttpTransportProperties.Authenticator();
// Add user creadentials to the transport header
// This user belongs to the 'facilelogin' group in AD
authenticator.setUsername("administrator");
authenticator.setPassword("prabath");
authenticator.setRealm("facilelogin");

properties = new Properties();
properties.put(org.apache.axis2.transport.http.HTTPConstants.AUTHENTICATE, authenticator);

options.setProperties(properties); 
client.setOptions(options);

response = client.sendReceive(getPayload());

System.out.println(response);
}

private static OMElement getPayload() {
OMFactory factory = null;
OMNamespace ns = null;
OMElement elem = null;
factory = OMAbstractFactory.getOMFactory();
ns = factory.createOMNamespace("http://axisversion.sample", "ns1");
elem = factory.createOMElement("getVersion", ns); 
return elem;
}
}