Showing posts with label wso2. Show all posts
Showing posts with label wso2. Show all posts

Wednesday, July 23, 2014

WSO2 IS SAML SSO using openSAML java library

In this blog post i will explain how to write a sample SSO service provider code using wso2is as the identity provider and openSAML as the supporting library to create SAML request.


First download the wso2IS from [1] and openSAML release from [2]. Then startup the wso2is. Create a new java web application project and import below jars from opensaml lib and lib/endorsed folders.


    serializer-2.10.0
    xalan-2.7.1
    xercesImpl-2.10.0
    xml-apis-2.10.0
    xmltooling-1.4.1
    xmlsec-1.5.6
    slf4j-api-1.7.5
    openws-1.5.1
    opensaml-2.6.1
    joda-time-2.2
    esapi-2.0.1
    commons-lang-2.6


Also include “axiom-api.jar” from apache axis project which has the UIDGenerator.java class.


Lets take our service provider name is “test.com” & our consumer landing page is “http://localhost:8080/test.com/home.jsp”. (You have to register a new service provider with above fields in wso2 identity server. To do so please refer [3] )


You can use below code to sent login & logout saml requests.




import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.StringWriter;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.zip.Deflater;
import java.util.zip.DeflaterOutputStream;

import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.joda.time.DateTime;
import org.opensaml.Configuration;
import org.opensaml.DefaultBootstrap;
import org.opensaml.common.SAMLVersion;
import org.opensaml.saml2.core.Assertion;
import org.opensaml.saml2.core.Attribute;
import org.opensaml.saml2.core.AttributeStatement;
import org.opensaml.saml2.core.AuthnContextClassRef;
import org.opensaml.saml2.core.AuthnContextComparisonTypeEnumeration;
import org.opensaml.saml2.core.AuthnRequest;
import org.opensaml.saml2.core.Issuer;
import org.opensaml.saml2.core.LogoutRequest;
import org.opensaml.saml2.core.NameID;
import org.opensaml.saml2.core.NameIDPolicy;
import org.opensaml.saml2.core.RequestAbstractType;
import org.opensaml.saml2.core.RequestedAuthnContext;
import org.opensaml.saml2.core.Response;
import org.opensaml.saml2.core.SessionIndex;
import org.opensaml.saml2.core.impl.AuthnContextClassRefBuilder;
import org.opensaml.saml2.core.impl.AuthnRequestBuilder;
import org.opensaml.saml2.core.impl.IssuerBuilder;
import org.opensaml.saml2.core.impl.LogoutRequestBuilder;
import org.opensaml.saml2.core.impl.NameIDBuilder;
import org.opensaml.saml2.core.impl.NameIDPolicyBuilder;
import org.opensaml.saml2.core.impl.RequestedAuthnContextBuilder;
import org.opensaml.saml2.core.impl.SessionIndexBuilder;
import org.opensaml.xml.ConfigurationException;
import org.opensaml.xml.XMLObject;
import org.opensaml.xml.XMLObjectBuilder;
import org.opensaml.xml.XMLObjectBuilderFactory;
import org.opensaml.xml.io.Marshaller;
import org.opensaml.xml.io.MarshallingException;
import org.opensaml.xml.io.Unmarshaller;
import org.opensaml.xml.io.UnmarshallerFactory;
import org.opensaml.xml.io.UnmarshallingException;
import org.opensaml.xml.util.Base64;
import org.opensaml.xml.util.XMLHelper;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;

import com.opensymphony.xwork2.util.logging.Logger;
import com.opensymphony.xwork2.util.logging.LoggerFactory;

public class SAMLConsumer {
    
    private static final Logger logger = LoggerFactory.getLogger(SAMLConsumer.class);
    private static boolean isBootstraped = false;

    private static final String ISSUER_URL = “test.com”;
    private static final String CONSUMER_URL = “http://localhost:8080/test.com/home.jsp”;

    private static final String NAME_SPACE_URI_ISSUER = “urn:oasis:names:tc:SAML:2.0:assertion”;
    private static final String NAME_SPACE_URI_AUTH = “urn:oasis:names:tc:SAML:2.0:protocol”;
    private static final String SAML_TRANSPORT_TYPE_PWD_PROTECTED = “urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport”;
    private static final String SAML_TRANSPORT_PROTOCOL_BINDING = “urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST”;
    
    private static final String LOCAL_NAME_ISSUER = “Issuer”;
    private static final String LOCAL_NAME_AUTHRQ = “AuthnRequest”;
    private static final String NAME_SPACE_PREFIX = “samlp”;
    private static final String AUTH_CNTXT_REF = “AuthnContextClassRef”;
    private static final String SAML = “saml”;
    
    public static String buildLoginRequest() throws IllegalArgumentException, SecurityException, IllegalAccessException, NoSuchFieldException, MarshallingException, IOException  {
        logger.info(“started”);

        IssuerBuilder issuerBuilder = new IssuerBuilder();
        Issuer issuer = issuerBuilder.buildObject(NAME_SPACE_URI_ISSUER, LOCAL_NAME_ISSUER, “samlp”);
        issuer.setValue(ISSUER_URL);
        
        NameIDPolicyBuilder nameIdPolicyBuilder = new NameIDPolicyBuilder();
        NameIDPolicy nameIdPolicy = nameIdPolicyBuilder.buildObject();
        nameIdPolicy.setFormat(“urn:oasis:names:tc:SAML:2.0:nameid-format:persistent”);
        nameIdPolicy.setSPNameQualifier(“Isser”);
        nameIdPolicy.setAllowCreate(new Boolean(true));
        
        AuthnContextClassRefBuilder authnContextClassRefBuilder = new AuthnContextClassRefBuilder();
        AuthnContextClassRef authnContextClassRef =
                                                    authnContextClassRefBuilder.buildObject(NAME_SPACE_URI_ISSUER,
                                                            AUTH_CNTXT_REF, SAML);
        authnContextClassRef.setAuthnContextClassRef(SAML_TRANSPORT_TYPE_PWD_PROTECTED);
        
        RequestedAuthnContextBuilder requestedAuthnContextBuilder =
                                                        new RequestedAuthnContextBuilder();
        RequestedAuthnContext requestedAuthnContext = requestedAuthnContextBuilder.buildObject();
        requestedAuthnContext.setComparison(AuthnContextComparisonTypeEnumeration.EXACT);
        requestedAuthnContext.getAuthnContextClassRefs().add(authnContextClassRef);
        
        DateTime issueInstant = new DateTime();
        AuthnRequestBuilder authnRequestBuilder = new AuthnRequestBuilder();
        AuthnRequest authnRequest = authnRequestBuilder.buildObject(NAME_SPACE_URI_AUTH, LOCAL_NAME_AUTHRQ, NAME_SPACE_PREFIX);
        authnRequest.setForceAuthn(new Boolean(false));
        authnRequest.setIsPassive(new Boolean(false));
        authnRequest.setIssueInstant(issueInstant);
        authnRequest.setProtocolBinding(SAML_TRANSPORT_PROTOCOL_BINDING);
        authnRequest.setAssertionConsumerServiceURL(CONSUMER_URL);
        authnRequest.setIssuer(issuer);
        authnRequest.setNameIDPolicy(nameIdPolicy);
        authnRequest.setRequestedAuthnContext(requestedAuthnContext);
        
        String authReqRandomId = Integer.toHexString(new Double(Math.random()).intValue());
        
        authnRequest.setID(authReqRandomId);
        authnRequest.setVersion(SAMLVersion.VERSION_20);
                
        return marshall(authnRequest);
        
    }
    
    public static String buildLogoutRequest(String user) throws MarshallingException, IOException {

        LogoutRequest logoutReq = new LogoutRequestBuilder().buildObject();

        logoutReq.setID(createID());

        DateTime issueInstant = new DateTime();
        logoutReq.setIssueInstant(issueInstant);
        logoutReq.setNotOnOrAfter(new DateTime(issueInstant.getMillis() + 5 * 60 * 1000));

        IssuerBuilder issuerBuilder = new IssuerBuilder();
        Issuer issuer = issuerBuilder.buildObject();
        issuer.setValue(ISSUER_URL);
        logoutReq.setIssuer(issuer);

        NameID nameId = new NameIDBuilder().buildObject();
        nameId.setFormat(“urn:oasis:names:tc:SAML:2.0:nameid-format:entity”);
        nameId.setValue(user);
        logoutReq.setNameID(nameId);

        SessionIndex sessionIndex = new SessionIndexBuilder().buildObject();
        sessionIndex.setSessionIndex(UIDGenerator.generateUID());
        logoutReq.getSessionIndexes().add(sessionIndex);

        logoutReq.setReason(“Single Logout”);

        return marshall(logoutReq);
    }
    
    private static String marshall(RequestAbstractType authnRequest) throws MarshallingException, IOException {
        doBootstrap();
        Marshaller marshaller = Configuration.getMarshallerFactory().getMarshaller(authnRequest);
        Element authDOM = marshaller.marshall(authnRequest);
        
        
        StringWriter rspWrt = new StringWriter();
        XMLHelper.writeNode(authDOM, rspWrt);
        String requestMessage = rspWrt.toString();
        
        System.out.println(requestMessage);
                 
        Deflater deflater = new Deflater(Deflater.DEFLATED, true);
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        DeflaterOutputStream deflaterOutputStream = new DeflaterOutputStream(byteArrayOutputStream, deflater);
        deflaterOutputStream.write(requestMessage.getBytes());
        deflaterOutputStream.close();
                 
        /* Encoding the compressed message */
        String encodedRequestMessage = Base64.encodeBytes(byteArrayOutputStream.toByteArray(), Base64.DONT_BREAK_LINES);
        String encodedAuthnRequest = URLEncoder.encode(encodedRequestMessage,”UTF-8”).trim();;
        
        return encodedAuthnRequest;
    }
    
    
    public static <T> T createSAMLObject(final Class<T> clazz) throws IllegalArgumentException, SecurityException, IllegalAccessException, NoSuchFieldException {
         XMLObjectBuilderFactory builderFactory = Configuration.getBuilderFactory();
        
         QName defaultElementName = (QName)clazz.getDeclaredField(“DEFAULT_ELEMENT_NAME”).get(null);
         Map<QName, XMLObjectBuilder> builderMap= builderFactory.getBuilders();
         System.out.println(“is nul “  + builderMap.get(defaultElementName));
        
        return null;
    }
    
    private static void doBootstrap() {
        if(!isBootstraped) {
            try {
                DefaultBootstrap.bootstrap();
                isBootstraped = true;
            } catch (ConfigurationException e) {
                logger.error(“Error calling bootstrap”, e);
            }
        }
    }
    
    public static Map<String, String> processResponse(String response) {

        XMLObject resp = null;
        
        try {
            resp = unmarshall(response);
        } catch (ConfigurationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ParserConfigurationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SAXException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (UnmarshallingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        return getResult(resp);
        
    }
    
    private static XMLObject unmarshall(String responseMessage) throws ConfigurationException,
                            ParserConfigurationException, SAXException, IOException, UnmarshallingException {
        
        doBootstrap();
        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
        documentBuilderFactory.setNamespaceAware(true);
        DocumentBuilder docBuilder = documentBuilderFactory.newDocumentBuilder();
        
        byte[] base64DecodedResponse = Base64.decode(responseMessage.trim());
        
        System.out.println(new String(base64DecodedResponse));
        
        ByteArrayInputStream is = new ByteArrayInputStream(base64DecodedResponse);
        
        Document document = docBuilder.parse(is);
        Element element = document.getDocumentElement();
        UnmarshallerFactory unmarshallerFactory = Configuration.getUnmarshallerFactory();
        Unmarshaller unmarshaller = unmarshallerFactory.getUnmarshaller(element);
        return unmarshaller.unmarshall(element);
        
    }
    
    private static Map<String, String> getResult(XMLObject responseXmlObj) {

        if (responseXmlObj.getDOM().getNodeName().equals(“saml2p:LogoutResponse”)) {
            logger.error(“user logout”);
            return null;
        }

        Response response = (Response) responseXmlObj;
        logger.info(“SAML resp” + response);

        Assertion assertion = response.getAssertions().get(0);
        Map<String, String> resutls = new HashMap<String, String>();

        /*
         * If the request has failed, the IDP shouldn’t send an assertion.
         * SSO profile spec 4.1.4.2 <Response> Usage
         */
        if (assertion != null) {

            String subject = assertion.getSubject().getNameID().getValue();
            resutls.put(“Subject”, subject); // get the subject

            List<AttributeStatement> attributeStatementList = assertion.getAttributeStatements();

            if (attributeStatementList != null) {
                // we have received attributes of user
                Iterator<AttributeStatement> attribStatIter = attributeStatementList.iterator();
                while (attribStatIter.hasNext()) {
                    AttributeStatement statment = attribStatIter.next();
                    List<Attribute> attributesList = statment.getAttributes();
                    Iterator<Attribute> attributesIter = attributesList.iterator();
                    while (attributesIter.hasNext()) {
                        Attribute attrib = attributesIter.next();
                        Element value = attrib.getAttributeValues().get(0).getDOM();
                        String attribValue = value.getTextContent();
                        resutls.put(attrib.getName(), attribValue);
                    }
                }
            }
        }
        return resutls;
    }
    
    public static String createID() {

        byte[] bytes = new byte[20]; // 160 bit
        
        new Random().nextBytes(bytes);
        
        char[] charMapping = {‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’, ‘g’, ‘h’, ‘i’, ‘j’, ‘k’, ‘l’, ‘m’, ‘n’, ‘o’, ‘p’};

        char[] chars = new char[40];

        for (int i = 0; i < bytes.length; i++) {
            int left = (bytes[i] » 4) & 0x0f;
            int right = bytes[i] & 0x0f;
            chars[i * 2] = charMapping[left];
            chars[i * 2 + 1] = charMapping[right];
        }

        return String.valueOf(chars);
    }
    
}




[1] http://wso2.com/products/identity-server/


[2] https://wiki.shibboleth.net/confluence/display/OpenSAML/Home


[3] http://pavithramadurangi.blogspot.com/2013/09/saml-20-sso-with-wso2-is-450.html

Tuesday, December 17, 2013

WSO2 ESB - sample REST to REST API configuration

<api xmlns=”http://ws.apache.org/ns/synapse” name=”TestApi” context=”/helloWorld”>
   <resource methods=”GET” url-mapping=”/hello”>
      <inSequence>
         <property name=”ContentType” value=”text/xml” scope=”axis2” type=”STRING”/>
         <switch source=”$axis2:HTTP_METHOD”>
            <case regex=”GET”>
               <property name=”HTTP_METHOD” value=”GET” scope=”axis2” type=”STRING”/>
            </case>
            <case regex=”POST”>
               <property name=”HTTP_METHOD” value=”POST” scope=”axis2” type=”STRING”/>
            </case>
            <default/>
         </switch>
         <log/>
         <send>
            <endpoint>
               <address uri=”http://localhost:8080/HelloRestFul” format=”pox”/>
            </endpoint>
         </send>
      </inSequence>
      <outSequence>
         <log/>
         <send/>
      </outSequence>
   </resource>
</api>
                       

Tuesday, December 3, 2013

WSO2 ESB exposing Web Service Proxy to a TCP client. ( A.K.A TCP proxy)

In this article I am going to explain how to create a proxy to a back end web service which accept TCP messages.


In our case our TCP client was sending a delimited string to the ESB and we need ESB to convert the delimited string into a SOAP/XML file and call the web service.


In our case we does not intend to send the response immediately back to the client rather than sending response as batches of several requests. Since I will explain how the batch response in another article.


To accept the TCP requests you need to change your axis2.xml file inside <ESB_LOCATION>/repository/conf/axis2.xml file and add below two transport handler.


1. Configure TCPTransportListener to listen to in coming TCP requests.


<transportReceiver name=”tcp” class=”org.apache.axis2.transport.tcp.TCPTransportListener”>
      <parameter name=”transport.tcp.port”>6060</parameter>
    </transportReceiver>


2. Configure TCPTransportSender to send responses over TCP (this handler will not want for this article but this will be used in next article for batch response sending )


<transportSender name=”tcp” class=”org.apache.axis2.transport.tcp.TCPTransportSender”/>


Then we use inbuilt smooks handler to transform the delimited values into a XML entries.


To do this we first need to add smooks configuration which act as a template to smooks handler. We need to add the smooks configuration as a local XML entry to ESB. To do this go to Main - > Service Bus -> Local Entries. And add a in-lined XML entry.


(This is an example of smooks configuration which use to trans form delimited text to XML)


<smooks-resource-list xmlns=”http://www.milyn.org/xsd/smooks-1.1.xsd” xmlns:csv=”http://www.milyn.org/xsd/smooks/csv-1.2.xsd”>
      <resource-config selector=”org.xml.sax.driver”>
         <resource>org.milyn.csv.CSVReader</resource>
         <param name=”fields”>id,password,userName</param>
         <param name=”rootElementName”>addLogin</param>
         <param name=”recordElementName”>login</param>
      </resource-config>
   </smooks-resource-list>
                                   


Then add a new proxy which use the smooks mediator in “Advance -> smooks”, with TCP transport type allowed, and finally with port and content type properties as below.


Below is a sample


<?xml version=”1.0” encoding=”UTF-8”?>
<proxy xmlns=”http://ws.apache.org/ns/synapse”
       name=”LoginProxy”
       transports=”tcp”
       statistics=”disable”
       trace=”disable”
       startOnLoad=”true”>
   <target>
      <inSequence>
         <smooks config-key=”LoginDetails”>
            <input type=”text”/>
            <output type=”xml”/>
         </smooks>
         <send>
            <endpoint>
               <wsdl service=”HelloServiceImplService”
                     port=”HelloServiceImpl”
                     uri=”http://localhost:8080//HelloWebService/services/HelloServiceImpl?wsdl”/>
            </endpoint>
         </send>
         <log level=”full”/>
      </inSequence>
      <outSequence>
         <log/>
      </outSequence>
   </target>
   <parameter name=”transport.tcp.port”>9446</parameter>
   <parameter name=”transport.tcp.contentType”>text/plain</parameter>
   <description/>
</proxy>

Wednesday, October 2, 2013

I WSO2ESB start up failed and hangout due to typo of wsdl saved in governance registry

Ok first of all i will tell what happened before the start up fail.


1. We have added a wsdl file belong to one of our services into the governance registry.


2. While manually editing the wsdl file which have been added to governance registry, some miss typing has occurred which changed a letter of one of the XML tags into upper case


3. Without knowing about the typo we saved the wsdl, (and here is the funny part… ) ESB let that wsdl to be save in it’s governance registry without parsing it or neither complaining us about the typo we did .. ( really ??? an enterprise level ESB does not check the documents edited ??? )



4. After some time for some reason we have restarted the ESB. ( and here the fun began. ) ESB hangout printing an exception complaining XML parsing error when it try to load that wsdl file where the error happened. And the admin console is not loading because OSGI module that correspond to esb (Synapsys) is waiting until all the wsdl loads. (This is the biggest fault - not letting other services, and esb to start because a wsdl typo occurred where it should parse the wsdl before save it to registry )


At the end of the console we can see the following message printed time to time without starting the ESB and the services due to what happened that has been described above.


 StartupFinalizerServiceComponent Waiting for required OSGi services: org.wso2.carbon.mediation.initializer.services.SynapseEnvironmentService


And this is the exception which complains about that our wsdl could not be parsed at startup.


WstxParsingException: Illegal processing instruction target (“xml”); xml (case insensitive) is reserved by the specs. at [row,col


There were 0 documentation and no entry about how to handle such a situation.


According to this exception we guessed the work around for this problem is just to remove the erroneous wsdl file from the governance registry. But wso2esb it self should not let that wsdl added to the registry at the first place. Even it did add, there should be some way to remove the erroneous wsdl related proxy and start up the esb and other proxy services. But it does not have that feature yet.


So how the hell we edit the governance registry without esb up.


Well, there is no proper way wso2 has exposed to do that. ( i could not find any thing on the web that’s why i write this blog entry apart from that to complement wso2 esb team about this s:D )



What we did is this,


1. Shut down the esb , copy and back up the databases folder in <wso2esb_home>/repository/database


2. Download any sql viewer tool that support h2 database management system. (yes wso2 default database is java h2 DBMS - in our case we used the default DBMS ). I used SQL Squirrel with h2 database jdbc driver.


3. open/connect to the h2 database in above folder using the sql tool.


4. find the “REG_RESOURCE” and “REG_CONTENT” tables in “WSO2CARBON_DB/PUBLIC/TABLE/” location.


5. search for erroneous wsdl file name inside “REG_RESOURCE” (hint: use sql select). File name for a resource in “REG_RESOURCE” saved in “REG_NAME” column. 


6. From the resulted row note down the value of “REG_CONTENT_ID” and search for that REG_CONTENT_ID in “REG_CONTENT” table. The resulting row is where the actual wsdl file saved as sql BLOB file type.


select rc.REG_CONTENT_ID from REG_RESOURCE rr, REG_CONTENT rc where rr.REG_NAME like ‘%mywsdl.wsdl’ and rc.REG_CONTENT_ID=rr.REG_CONTENT_ID


7. To recover the wso2 esb from hanging out due to this erroneous wsdl remove the two entries related to REG_CONTENT_ID of REG_NAME of the wsdl from two tables.


8. Re start the wso2esb and you may find that exceptions are no more there and server does not hanging out any more.



Yeah i know this is bit fishy and fundamental, but if we cant access the admin console due to that ESB not finishing up loading its OSGI module (because esb let it save error-nous wsdl inside the governance registry at the first place.) we cant do much rather than cracking the database and remove the wsdl manually right ??


PS : there may be other artifacts such as proxies, sequences, endpoints using the removed wsdl, that may affected by the removal. so i instruct to remove those of which use the removed wsdl.





Wednesday, September 4, 2013

Configure WSO2 Identity server to use Apache DS LDAP

1. Configure a LDAP from Apache DS.


To configure Apache DS first download the latest version of apache directory studio from here.


Then install the setup (for windows users) and start the Apache Directory Studio.


Then go to “Window - > show view -> other ” and select “LDAP servers”.



In the server view click on “new server” and create a new server instance. Start the server by right clicking on the server instance and click on “start”.



Then go to connections tab next to the LDAP servers tab and create a new connection.



This will open “New LDAP Connection" wizard.



Enter the connection details and click next. (Here in my example i run on localhost port 10389.)


In the next window you will be asked for parameters for authentication details.



Enter the parameters for simple authentication. In the Bind DN or user field, enter the DN of the administrator’s account on the directory server (for the default instance of the Apache directory server, this is uid=admin,ou=system). In the Bind password field, enter the administrator’s password (for the default instance of the Apache directory server, the administrator’s password is secret). Click Finish


If the connection is successfully established, you should see an outline of the Directory Information Tree (DIT) in the LDAP Browser view. In the LDAP Browser view, drill down to the ou=users node, as shown.




Right-click on the ou=users node and select New Entry. The New Entry wizard appears. Leave the Entry Creation Method by clicking next. In the Object Classes pane, select inetOrgPerson from the list of Available object classes on the left and then click Add to populate the list of Selected object classes. Click Next.



In the Distinguished Name pane, complete the RDN field, putting uid in front and jdoe after the equals sign. Click Next.



Fill in the remaining mandatory attributes in the Attributes pane. Set the cn (common name) attribute to John Doe and the sn (surname) attribute to Doe. Click Finish.



To add a userPassword attribute to the user entry. In the LDAP Browser view, you should now be able to see a new node, uid=jdoe. Select the uid=jdoe node. Now, right-click in the Entry Editor view and select New Attribute. The New Attribute wizard appears. From the Attribute type drop-down list, select userPassword. Click Finish. The Password Editor dialog appears. In the Enter New Password field, enter the password, secret. Click Ok.


Point wso2 Identity server to the newly created external LDAP


Goto Identity server root folder and browse in to “wso2esb-{version}\repository\conf”. Open “user-mgt.xml” in the editor.


Un-comment the commented section about external LDAP.




Change the password of connection as following line. (since our previously entered default password is “secret” we entered that below)


<Property name=”ConnectionPassword”>secret</Property>


Run the Identity server and create a new user by signup.


If all goes correctly you may be able to add new users by Identity server and, in Apache DS you may see the newly added  users.