Wednesday, April 29, 2015

Deploy InfoRecoverySample in WSO2 IS

Steps:
WSO2IS 5.0.0

1. Download the source code from
https://svn.wso2.org/repos/wso2/carbon/platform/branches/turing/products/is/5.1.0/modules/samples/InfoRecoverySample/

2. Configure the following in web.xml file
a. Specify the "carbonServerUrl" with the URL of the Identity Server. eg: https://localhost:9443
b. Specify the credentials to access Identity Server, "accessUsername" as admin and "accessPassword" as admin.
c. Specify the trustStore absolute resource path for "trustStorePath", eg: <IS_HOME>
/repository/resources/security/client-truststore.jks

3. Update the following entry in sso.properties file
SAML.ConsumerUrl=https://localhost:9443/InfoRecoverySample/home.jsp

4. Exclude the slf4j-api jar from pom.xml file.

<dependency>
  <groupId>org.wso2.carbon</groupId>
  <artifactId>org.wso2.carbon.identity.sso.agent</artifactId>
  <version>1.2.0</version>
  <exclusions>
  <exclusion>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-api</artifactId>
  </exclusion>
  </exclusions>
</dependency>

4. Build the source mvn clean install

5. Copy the InfoRecoverySample.war to the <IS_HOME>/repository/deployment/server/webapps 

6. Configure the email confirmation links.
a. To configure for password reset call back in Identity Server (in <IS_HOME>/repository/conf/email/email-admin-config.xml with email type as type="passwordReset")
according to the sample as follows. This will be the confirmation handler path of the user's confirmation.

Eg:

<configuration type="passwordReset">
<targetEpr>https://localhost:9443/InfoRecoverySample/infoRecover/verify</targetEpr>
<subject>WSO2 Carbon - Password Reset</subject>
<body>
Hi {first-name}
We received a request to change the password on the {user-name} account associated with this e-mail address. If you made this request, please click the link below to securely change your password:

https://localhost:9443/InfoRecoverySample/infoRecover/verify?username={user-name}&amp;confirmation={confirmation-code}

If clicking the link doesn't seem to work, you can copy and paste the link into your browser's address window.
If you did not request to have your {user-name} password reset, simply disregard this email and no changes to your account will be made.
</body>
<footer>
Best Regards,
WSO2 Carbon Team
http://www.wso2.com
</footer>
<redirectPath></redirectPath>
</configuration>

Please refer the Identity Server documentation for sample email template in https://docs.wso2.com/display/IS500/Recover+with+Notification

b. To configure for account confirmation in Self sign up provide the configuration in email-admin-config.xml
with email type as "accountConfirmation". Following is the call back handler for the sample.
<targetEpr>https://localhost:9443/InfoRecoverySample/confirmReg</targetEpr>

7. Configure the identity-mgt.properties file attributes as follows in the Identity Server (in <IS_HOME>/repository/conf/security/identity-mgt.properties)

Identity.Listener.Enable=true
Notification.Sending.Enable=true
Notification.Expire.Time=7200
Notification.Sending.Internally.Managed=true
UserAccount.Recovery.Enable=true
Captcha.Verification.Internally.Managed=true



8. Edit the axis.xml file with the following configuration. This file is found in the <IS_HOME>/repository/conf/axis2/directory. Uncomment the following in the file and provide the necessary email settings.

<transportSender name="mailto"

class="org.apache.axis2.transport.mail.MailTransportSender">
    <parameter name="mail.smtp.from">sampleemail@gmail.com</parameter>
    <parameter name="mail.smtp.user">sampleemail</parameter>
    <parameter name="mail.smtp.password">password</parameter>
    <parameter name="mail.smtp.host">smtp.gmail.com</parameter>
    <parameter name="mail.smtp.port">587</parameter>
    <parameter name="mail.smtp.starttls.enable">true</parameter>
    <parameter name="mail.smtp.auth">true</parameter>
</transportSender>

9. Now restart the server and register new SP as shown in the image below
 
Assertion Consumer URL = https://localhost:9443/InfoRecoverySample/home.jsp
Enable Single Logout = https://localhost:9443/InfoRecoverySample/home.jsp

10: Access the sample with https://localhost:9443/InfoRecoverySample

Refer: 
https://svn.wso2.org/repos/wso2/carbon/platform/branches/turing/products/is/5.1.0/modules/samples/InfoRecoverySample/README.txt

Configure Active Directory as a Secondary User Store


Prerequisites:

Install and configure Active directory with WSO2 IS 5.0.0
http://social.technet.microsoft.com/wiki/contents/articles/2980.ldap-over-ssl-ldaps-certificate.aspx

Steps to configure secondary user store:

1. Login as admin/admin
2. Go to Configure -> User Store Management, Add secondary user store, give the information as shown in the image, click update


Refer https://docs.wso2.com/display/IS500/Configuring+Secondary+User+Stores

Verify:

1. The secondary user store configuration should be found at the following location
<IS_HOME>/repository/deployment/server/userstores/ADSUS.xml

2. Create a new user in secondary user store and check that user can login to the management console.
Go to configure -> User and Roles -> Users -> Add New User (ex: aduser)
Select the domain ADSUS and give the user details and Finish
Go to Roles and give the login permission to the Internal/Everyone role.
Note: Internal/Everyone role automatically assign to any user

Now logout and try to login with aduser

Saturday, April 25, 2015

VFS to SFTP cannot access absolute paths

Learn WSO2 ESB VFS Transport

When sending or receiving files with VFS transport to a SFTP folder, the specified path is relative to the user home, not a absolute path.

Eg:  If the URL is vfs:sftp://user:password@ftp.server.com/myPath, the file will be stored at /home/user/myPath not in /myPath


This is how SFTP protocol works. SFTP uses SSH protocol to communicate with the server, so it always log in to the users home directory and then it takes the path relative to the user home directory. That is why this behavior occurs.


If you need to access the different location instead of user home


Solution 1:


This is not supported in WSO2 ESB 4.8.1.


So as a workaroud you can mount /myPath to the /home/user/myPath location and then make sure user have access to the /myPath.


mount --bind /myPath /home/user/myPath


Solution 2:


This will be available in next version WSO2 ESB 4.9.0.



"sftpPathFromRoot=true" needs to be added to the URL if absolute paths are used

<parameter name="transport.vfs.FileURI">vfs:sftp://user:password@ftp.server.com/myPath?sftpPathFromRoot=true</parameter>


https://wso2.org/jira/browse/ESBJAVA-3405



Run multiple samples without restarting the WSO2 ESB

WSO2 ESB includes working examples that demonstrate its features and capabilities.

When executing ESB samples, each time we need to restart the ESB server as:
Please note: if a given sample required to change axis2.xml file or add some libraries to the ESB, then need to restart the ESB.

./wso2esb-samples.sh -sn 0


How to run multiple samples without restarting the WSO2 ESB:

Solution 1:

The simplest way is just copy the configuration from the ESB docs and paste it on ESB source view and update: then it will deploy the new synapse config to the ESB_HOME/repository/deployment/server/synapse-configs/default

Solution 2:

Create a CAR file and deploy it to the ESB.

We can use the WSO2 Developer Studio for create CAR files


VFS access SFTP with special character password

Learn WSO2 ESB VFS Transport
https://docs.wso2.com/display/ESB481/VFS+Transport

When we need to access the FTP server using SFTP, VFS connection-specific URL need to be given as :

<parameter name="transport.vfs.FileURI">vfs:sftp://username:p@ssword@ftp.server.com/filePath?vfs.passive=true</parameter>

When the password contains a special characters (eg: p@ssword), it gives the following error.

2015-03-27 13:06:03,766 [-] [PassThroughMessageProcessor-5] ERROR VFSTransportSender cannot resolve replyFile
org.apache.commons.vfs2.FileSystemException: Invalid absolute URI "sftp://username:***@ftp.server.com/filePath?vfs.passive=true".

Solution 1:

Replace the special characters with the respective hex representation.

<parameter name="transport.vfs.FileURI">vfs:sftp://username:p%40ssword@ftp.server.com/filePath?vfs.passive=true</parameter>

    Char     Hex Code
    -------  --------
    [space]    %20
       "       %22
       #       %23
       $       %24
       %       %25
       &       %26
       '       %27
       (       %28
       )       %29
       *       %2A
       +       %2B
       ,       %2C
       -       %2D
       .       %2E
       /       %2F
       :       %3A
       ;       %3B
       <       %3C
       =       %3D
       >       %3E
       ?       %3F
       @       %40
       \       %5C
       ^       %5E
       `       %60
       |       %7C

Solution 2:

Change the password to plain text password without any special characters :)

Wednesday, April 22, 2015

Send email via WSO2 ESB with several attachments

WSO2 ESB Mail transport allows you to send a email only with 1 attachment. If you want to send number of attachments here's the solution.

Scenario: Here I want to extract some content from the input message and attach to the email as two different attachment.

Solution: You can achieve this requirement using Gmail connector.

Steps: 

  1. Add the Gmail connector to the ESB and enable it.

  1. Setup the scenario: split the input message and send it with an email using two different attachments.
    1. Input message I used
<email>
       <username>sender@gmail.com</username>
       <password>password</password>
       <subject>This is the subject of the mail</subject>
       <toRecipients>receiver@gmail.com</toRecipients>   
       <textContent>This is the text content of the mail</textContent>      
       <part1>Content of the Part 1</part1>
       <part2>Content of the Part 2</part2>      
</email>

  1. proxy configuration
<proxy xmlns="http://ws.apache.org/ns/synapse"
      name="gmailProxy"
      transports="https,http"
      statistics="disable"
      trace="disable"
      startOnLoad="true">
  <target>
     <inSequence>
        <property name="username" expression="//username/text()"/>
        <property name="password" expression="//password/text()"/>
        <property name="subject" expression="//subject/text()"/>
        <property name="toRecipients" expression="//toRecipients/text()"/>
        <property name="textContent" expression="//textContent/text()"/>
        <class name="org.test.mediator.SimpleClassMediator"/>
        <property name="FORCE_SC_ACCEPTED" value="true" scope="axis2"/>
        <gmail.passwordLogin>
           <username>{$ctx:username}</username>
           <password>{$ctx:password}</password>
        </gmail.passwordLogin>
        <log level="custom">
           <property name="login" value="success"/>
        </log>
        <gmail.sendMail>
           <subject>{$ctx:subject}</subject>
           <toRecipients>{$ctx:toRecipients}</toRecipients>
           <textContent>{$ctx:textContent}</textContent>
           <attachmentIDs>part1.txt,part2.txt</attachmentIDs>
        </gmail.sendMail>
     </inSequence>
  </target>
  <description/>
</proxy>

  1. Develop a custom class mediator to split the message parts and add it to the synapse MessageContext as attachments. 
          Refer https://docs.wso2.com/display/ESB481/Writing+a+WSO2+ESB+Mediator
          Here is the custom class mediator I wrote for this scenario 

package org.test.mediator;

import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.xpath.AXIOMXPath;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.synapse.MessageContext;
import org.apache.synapse.core.axis2.Axis2MessageContext;
import org.apache.synapse.mediators.AbstractMediator;
import org.jaxen.JaxenException;

import javax.activation.DataHandler;
import javax.mail.util.ByteArrayDataSource;

public class SimpleClassMediator extends AbstractMediator {

  private static final Log log = LogFactory.getLog(SimpleClassMediator.class);

  @Override public boolean mediate(MessageContext messageContext) {
      OMElement bodyContent = messageContext.getEnvelope().getBody().getFirstElement();
      try {
          AXIOMXPath xPathPart1 = new AXIOMXPath("//part1");
          String part1 = ((OMElement) xPathPart1.selectSingleNode(bodyContent)).getText();

          AXIOMXPath xPathPart2 = new AXIOMXPath("//part2");
          String part2 = ((OMElement) xPathPart2.selectSingleNode(bodyContent)).getText();

          org.apache.axis2.context.MessageContext axis2MsgCtx =
              ((Axis2MessageContext) messageContext).getAxis2MessageContext();

          javax.activation.DataHandler handler1 = new DataHandler(new ByteArrayDataSource(part1.getBytes(), "text/plain"));
          axis2MsgCtx.addAttachment("part1.txt", handler1 );

          javax.activation.DataHandler handler2 = new DataHandler(new ByteArrayDataSource(part2.getBytes(), "text/plain"));
          axis2MsgCtx.addAttachment("part2.txt", handler2);

      } catch (JaxenException e) {
          log.error("Error while adding attachments...", e);
      }

      return true;
  }

Now the setup is done, restart the ESB and send the request.
(Versions: ESB 4.8.1, Gmail Connector 1.0.0)

More reading: http://wso2.com/library/1148/