Solve: “No subject alternative DNS name matching” error

I have been working on countless situations on solving SSL related issues, but today I have came across with a new one.


Caused by: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative DNS name matching is-1.example.com.cloud found.
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1904)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:279)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:273)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1446)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:209)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:913)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:849)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1023)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1332)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1359)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1343)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:153)
at org.apache.jsp.login_jsp._jspService(login_jsp.java:756)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:439)
... 41 more
Caused by: java.security.cert.CertificateException: No subject alternative DNS name matching is-1.example.com.cloud found.
at sun.security.util.HostnameChecker.matchDNS(HostnameChecker.java:204)
at sun.security.util.HostnameChecker.match(HostnameChecker.java:95)
at sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:347)
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:203)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:126)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1428)
... 55 more

No subject alternative DNS name matching  found

By reading  this post and this post I understood that, this SAN is an extension can used to cover multiple hostnames using a single certificate. Using a wildcard certificate it can achieve the similar requirements of covering multiple domains from one certificate. But using the SAN extension has more flexibility to whitelist different domains that not belong to same pattern.

Going back to the error, when I browse the server certificate and check on the details on the SAN extension, it was figured that this particular internal hostname not included in the DNS list. As the fix it was changed to request endpoint to use correct hostname.

Few usages on SAN extension on popular domains:

  1. Facebook (Browed using Firefox)
  2. GMail (Browser using Chrome)
  3. WordPress (Browser using Chrome)

In summary SAN extension provide flexibility to add multiple domains covered by the single certificate while providing the hostname verification during the SSL handshake. If you need more details on the hostname verification read this post.

That’s all for now.. Hope you learned something.. 🙂

FREAK Vulnerability and Disabling weak export cipher suites in WSO2 Carbon 4.2.0 Based Products

A group of researchers from Microsoft Research, INRIA and IMDEA have discovered a serious vulnerability in some SSL\TLS servers and clients, that allows a man in the middle attacker to downgrade the security of the SSL\TLS connection and gain the access to all the encrypted data transferred between client and server.

Web servers which supports export ciphers are vulnerable to the FREAK attack. The attack is carried out in a way that attacker can downgrade the connection to the web server from strong RSA to (weak) export grade RSA cipher, and get a message signed with the weak RSA key. Quoting smacktl.com [2],

Thus, if a server is willing to negotiate an export ciphersuite, a man-in-the-middle may trick a browser (which normally doesn’t allow it) to use a weak export key. By design, export RSA moduli must be less than 512 bits long; hence, they can be factored in less than 12 hours for $100 on Amazon EC2.

Now you can understand the severity of this vulnerability. If you want to learn more on the FREAK attack, there are good references listed at the bottom on this post.

Now lets have a look at the most important part, How to avoid FREAK in WSO2 Carbon products?

In order to avoid FREAK vulnerability, the web server should avoid supporting weak export-grade RSA ciphers.

How to disable weak export cipher suites in WSO2 Carbon 4.2.0 Based Products.

The cipher set used in a carbon server is defined by the embedded tomcat server. So this configuration should be done in “catalina-server.xml”.

  1. Open <CARBON_HOME>//repository/conf/tomcat/catalina-server.xml file.
  2. Find the Connector configuration corresponding to TLS. Usually there are only two connector configurations and connector corrosponding to TLS have connector property, SSLEnabled=”true”.
  3. Add new property “ciphers” inside the TLS connector configurations with the value as follows,
    • If you are using tomcat version 7.0.34,
      ciphers="SSL_RSA_WITH_RC4_128_MD5,SSL_RSA_WITH_RC4_128_SHA,SSL_DHE_RSA_WITH_DES_CBC_SHA,SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA,SSL_RSA_WITH_DES_CBC_SHA,SSL_RSA_WITH_3DES_EDE_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_RSA_WITH_AES_128_CBC_SHA"
      
    • If you are using tomcat version 7.0.59,
      ciphers="SSL_RSA_WITH_RC4_128_MD5,SSL_RSA_WITH_RC4_128_SHA,SSL_DHE_RSA_WITH_DES_CBC_SHA,SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_DHE_RSA_WITH_AES_256_CBC_SHA"
      
  4. Restart the server.

Now to verify whether all configurations are set correctly, you can run TestSSLServer.jar which can be downloaded from here.

$ java -jar TestSSLServer.jar localhost 9443

In the output you get running above command, there is a section called “Supported cipher suites”.

Supported cipher suites (ORDER IS NOT SIGNIFICANT):

SSLv3

RSA_WITH_RC4_128_MD5

RSA_WITH_RC4_128_SHA

DHE_RSA_WITH_DES_CBC_SHA

DHE_RSA_WITH_3DES_EDE_CBC_SHA

RSA_WITH_AES_128_CBC_SHA

DHE_RSA_WITH_AES_128_CBC_SHA

(TLSv1.0: idem

If all configurations are set correctly, it should not contain any export ciphers (like “RSA_EXPORT_WITH_RC4_40_MD5”, “RSA_EXPORT_WITH_DES40_CBC_SHA” or “DHE_RSA_EXPORT_WITH_DES40_CBC_SHA”). Output should be similar to above.

Cipher suites supported in the carbon products is defined by the java version of the server running on, hence the output you see when you run might differ from the above output. Bottom line is the list should not contain any ciphers which have “_EXPORT_” in its name.

References :

[1] Washingtonpost article on FREAK : http://www.washingtonpost.com/blogs/the-switch/wp/2015/03/03/freak-flaw-undermines-security-for-apple-and-google-users-researchers-discover/

[2] “SMACK: State Machine AttaCKs” : https://www.smacktls.com/

[3] “Attack of the week: FREAK (or ‘factoring the NSA for fun and profit’)” : http://blog.cryptographyengineering.com/2015/03/attack-of-week-freak-or-factoring-nsa.html

[4] “Akamai Addresses CVE 2015-0204 Vulnerability” : https://blogs.akamai.com/2015/03/cve-2015-0204-getting-out-of-the-export-business.html

Provision users to Google using WSO2 Identity Server

The latest release of WSO2 Identity Server 5.0.0 is just couple of weeks away and its powered with a whole lot of features like,

  • seamless identity federation with new Authentication Framework
  • new User View Portal and improvements to server management console… and most importantly,
  • simple way to provision users to different domains with new Identity Provisioning Framework

To provision users to a Google domain; the last feature – Identity Provisioning Framework is the module working behind the screen. As prerequisites, following details about the Google domain are needed later for configuration,

  1. A Google domain
  2. A service account for above domain (which provides service account email and a private key)
  3. Email of the Service account owner

If you find any trouble finding above details, I have planned to come up with a post on that. Until then drop a comment if you find any trouble.

So lets get started with downloading Identity Server.

Step 1 : Download the latest beta pack of Identity Server from here : https://svn.wso2.org/repos/wso2/scratch/IS-5.0.0/beta/. Then extract it to a folder which we’ll refer as <IS_HOME> from here onwards.

Step 2 : Copy downloaded private key (prerequisite #2) to <IS_HOME>/repository/deployment/server/ folder and rename it as “google-privatekey.p12”.

Step 3 : Start the server by running <IS_HOME>/bin/wso2server.sh (use wso2server.bat in you are in windows)

Step 4 : Now we want to define Google IdP to provision our users. So we want to register our Google domain as Identity Provider. To do so,

    • Go to https://localhost:9443/carbon/admin/login.jsp login using credentials admin : admin.
    • In the Main tab click on Identity Providers ->Add button which is listed under Identity section
    • Add an Identity Provider as follows,
      • Fill Basic Information,
        • SetIdentity Provider Name : Google-IdP
        • Description : The remote Google IdP which users need to be provisioned

Google IdP Configurations

      • To register provisioning configurations for google, click on Outbound Provisioning Connectors -> Google Provisioning Configuration 
      • Provide
        • Tick on Enable Connector check box
        • Tick on Default Connector checkbox
        • Enter your Google Domain name. For example use wso2is.mygbiz.com  (prerequisite #1)
        • Select claim URI for Primary Email. For example choose http://wso2.org/claims/emailaddress
        • Select claim URI for Given Name. For example choose http://wso2.org/claims/givenname
        • Enter a default value for Given Name. For example use Foouser
        • Select claim URI for Family Name. For example choose http://wso2.org/claims/lastname
        • Enter a default value for Family Name. For example use Foofamily
        • Enter your Service Account Email address. For example use 8274902257-r6q8t11mro2r9l8qpa32rtk3d6jnj35s@developer.gserviceaccount.com (prerequisite #2)
        • Enter your Administrator’s Email address. For example use darshana@wso2is.mygbiz.com (prerequisite #3)
        • Enter an Application Name to identify requests from this client. For example use Google-Prov-Client-in-IS
    • Click on Register button at the bottom to finish

Google Connector Configurations

Step 5 : Now we should associate created IdP with an application. By doing so, created Google-IdP will get triggered when that application send a provisioning request. Here we’ll associate Google-IdP with Resident SP. Resident SP is a special application. In simple terms it represents Carbon Management Console as an application. To do so,

    • Click on Service Providers -> List button which is listed under Identity section
    • In the Service Providers list page, click on Resident Service Provider link to edit configurations of Resident SP
    • Associate created IdP with Resident SP as follows,
      • Click on Outbound Provisioning Configuration panel, select Google-IdP (which created above) from the list and click on + button. This will do the association.
      • Make sure you have googleapps selected in the dropdown list of the Google-IdP which indicate connector mechanism for specified IdP.
    • Click on Update button to finish

Associating Google IdP with Resident SP

Step 6 : Now all set.. What we have to do is test the scenario. Simply create an user in IS. You can do that as follows,

    • Click on Configure tab
    • Click on Users and Roles
    • In User Management page click on Users icon
    • In Click on Add New User link
    • Provide username, password  for new user and then click on Finish button.

If everything was set up accordingly, now the user would created in Identity Server upon successful user creation in Google domain. You could verify the if the user created by logging in to the admin console of the domain. In my case its https://admin.google.com/wso2stg.mygbiz.com/AdminHome. There you can see created users under User tab.

 Thats it.. Its was only a couple of configurations switching on the functionality and obtaining authentication details and now you can automatically create Google accounts for Identity Server users. The full advantage of provisioning users to google comes with enabling SSO for Google domain and pointing IdP as Identity Server. Configuring that is even easier than this. Keep tuned, will come with a post on that soon..

WSO2 ESB 4.8.1 proven as the fastest ESB…

A recent performance study esb-performance-round-7.5  show that the WSO2 ESB has outperforms all others and continues to claim its name as the fastest ESB while been opensource.

Above article based on the latest 4.8.1 version of WSO2 ESB which was released early this year and comparison has done against with number of leading open source ESBs.

graph

table

Finally, its worthy to quote the conclusion of the article,

“This article presents the results of an open and repeatable performance study comparing WSO2 ESB 4.8.1, Mule ESB 3.4.0, Talend-SE 5.3.1, and UltraESB 2.0.0. The results indicate that WSO2 ESB 4.8.1 has continued to outperform all other compared ESBs in almost all scenarios.”

Interested? Don’t miss the full article.

REST APIs for WSO2 Identity Server

Currently* WSO2 Identity Server provides SOAP APIs for most of its functionalities. But if you want to access them in RESTful manner, no worries its just couple of things to needed to be done to expose them as REST APIs.

There can be several ways to do this but here we are going to do that by fronting SOAP service from a REST proxy using WSO2 ESB.  This pattern not only limited to WSO2 Identity Server, you could use same for any WSO2 Product.

Before we start, you need to download WSO2 Identity Server and WSO2 ESB. Here we are using WSO2 Identity Server 4.6.0 and WSO2 ESB 4.8.1.

Lets say you wanted to use some functionality of WSO2 Identity Server such as authentication using a REST API. First you need to find the relevant SOAP service, for the Authentication we are going to use “AuthenticationAdmin” service.

There are only 3 steps to whole process.

1. “The Easiest” : Start WSO2 Identity Server. 

Since we are going to start two WSO2 servers on same machine it will make a conflict on ports by two servers. So we are going to set port offset to 1 in WSO2 Identity Server. Open <IS_HOME>/repository/conf/carbon.xml file and search for tag “Offset” and set it to 1 as , <Offset>1</Offset>.

And also its better to search for the tag “HideAdminServiceWSDLs” and set it value to false as, <HideAdminServiceWSDLs>false</HideAdminServiceWSDLs>.  By default WSO2 servers doesn’t publish wsdls and later in this post we’ll find it’s easier to generate message content if we have the wsdl.

Save the changes in carbon.xml and goto <IS_HOME>/bin/ directory and start WSO2 Identity Server by running wso2server.sh (for linux) or wso2server.bat (for windows).

2. “The Brain” : Start WSO2 ESB and create the Proxy which do the thing

Since we take care of the conflicts running two WSO2 servers in single machine in the step 1, we can start the ESB staright away by running wso2server.sh (for linux) or wso2server.bat (for windows) in <ESB_HOME>/bin/ directory.

Now we have to create proxy service which fronts our SOAP service in RESTful manner. Goto ESB management console, in the “Main” tab click on (“Services” -> “Add” ->) “Proxy Service”. Click on “Custom Proxy”, and then click on the link “switch to source view” on the top of the pane. It will switch you to source view of the proxy, now replace the generated content by copying below proxy and click on Save.

<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
       name="AuthenticationAdminProxy"
       transports="https"
       statistics="disable"
       trace="disable"
       startOnLoad="true">
   <target>
      <inSequence>
         <header name="Action" expression="get-property('transport', 'Action')"/>
      </inSequence>
      <outSequence>
         <send/>
      </outSequence>
      <endpoint>
         <address uri="https://localhost:9444/services/AuthenticationAdmin.AuthenticationAdminHttpsSoap11Endpoint/"
                  format="soap11"/>
      </endpoint>
   </target>
   <description/>
</proxy>

There are only four things to notice in this proxy.

i. The name of the proxy : This is defined in under the “name” attribute of the proxy and we have given the name “AuthenticationAdminProxy” which will be needed for step3.

ii. Transports of the proxy : The “transport” attribute of the proxy defines allowed transports for a proxy. Here we have allowed only “https” transport since this proxy handles sensitive info.

iii. Header mediator : To invoke backend SOAP service it is required to include the header “SOAPAction“. To do so we have added this header mediator which pick the value from the header “Action” of incoming request to the proxy and set it as the value of “SOAPAction” header.

iv. Endpoint address : This where we define the address of the backend SOAP service. In the endpoint address port number 9444 is used since we have started the WSO2 Identity Server with a port offset 1.

That’s all for ESB configuration. Next we are on to the last step.

3. “The Show” : Just run the curl

Now we have left to do is try out what we have built. You can use following CURL command to call our proxy which have the endpoint URL https://localhost:8243/services/AuthenticationAdminProxy&#8221;. Note we have included the header “Action” which will be used as described in step 2-iii.

curl -k -H 'Content-Type: application/xml; charset=UTF-8' -H 'Action:"urn:login"' -d 'adminadmin' "https://localhost:8243/services/AuthenticationAdminProxy"

Since we have sent the valide credentials it will returns a response like following,

<ns:loginResponse xmlns:ns="http://authentication.services.core.carbon.wso2.org"><ns:return>true</ns:return></ns:loginResponse>

To generate the body of the curl request i have used soap ui, and this is where you find the benefit of making wsdls visible. You can try the same for any service, only you have to do is create the proxy and make the request with correct parameters.

Before the finishing things off, i thought to share the proxy which i used to debug things while writing this post. It almost the same as the above proxy addition to couple of logs. You also may find it useful if you go deeper.

<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
       name="AuthenticationAdminProxy"
       transports="https"
       statistics="disable"
       trace="disable"
       startOnLoad="true">
   <target>
      <inSequence>
         <log level="full"/>
         <log level="custom">
            <property name="Lang" expression="get-property('transport', 'Action')"/>
         </log>
         <header name="Action" expression="get-property('transport', 'Action')"/>
         <log level="full"/>
      </inSequence>
      <outSequence>
         <log level="full"/>
         <send/>
         <log level="full"/>
      </outSequence>
      <endpoint>
         <address uri="https://localhost:9444/services/AuthenticationAdmin.AuthenticationAdminHttpsSoap11Endpoint/"
                  format="soap11"/>
      </endpoint>
   </target>
   <description/>
</proxy>

That’s all… Peace of cake.. Isnt it?

(* With the upcoming revolutionary Carbon 5 platform, all the WSO2 products will comes with FULL REST support in OOB.)

ref : http://docs.wso2.org/display/ESB481/Using+REST+with+a+Proxy+Service

Mutual SSL with WSO2 Identity Server

This post explains how to enable mutual ssl with WSO2 Identity Server. Here we used IdentityServer 4.5.0. But the same approach can be used for the other carbon based products too. 🙂

WSO2 Identity Server Side

  • Step 1:

First you need to download WSO2 Identity Server 4.5.0. This custom authenticator to makes Identity Server compatible with mutual ssl, so you would need to download it too. You could find the source code of the authenticator from here.

  • Step 2:

Open <IS_Home>/repository/conf/tomcat/catelina-server.xml file. Then add connector property, clientAuth=”true” to make server to (always) expect two-way SSL authentication. As an example I have attached my catelina-server.xml here.

And if you need to disable certificate authentication in certain occasions(like mobile apps), it could make two-way SSL authentication optional and use it if only possible by configuring clientAuth=”want” in catelina-server.xml file.

(Even though its not required for WSO2 product to configure tomcat’s key store explicitly, just for the information  if you ever needed specify the key store for tomcat, it could use ‘keystoreFile’ and ‘keystorePass’ attributes as described in here)

  • Step 3:

Copy the custom authenticator download in Step 1 to <IS_Home>/repository/components/dropins/ folder which is handling the mutual authentication in the IS server backend.

  • Step 4:

Extract WSO2 public certificate from <IS_Home>/repository/resources/security/wso2carbon.jks and add it to client’s trust store. Then add client’s public certificate to the trust store which can be find in <IS_Home>/repository/resources/security/client-truststore.jks. 

For example, goto <IS_Home>/repository/resources/security/ folder and use

keytool -export -alias wso2carbon -file carbon_public2.crt -keystore wso2carbon.jks -storepass wso2carbon

command to extract public certificate and use

keytool -import -trustcacerts -alias <Client_Alias> -file <Client_Public.crt> -keystore client-truststore.jks -storepass wso2carbon

command to import client’s certificate to wso2 trust store.

If you use same keystore for both client and server, step 4 wouldn’t be needed but its not recomended to use same key store

  • Step 5:

This also an optional step, but would be useful when tryout simulating a client using soap ui. WSDLs of admin services in WSO2 servers are hidden by default. But you wanted to change that behaviour, open <IS_Home>/repository/conf/carbon.xml file and change HideAdminServiceWSDLs property to false.

Thats all needed from Identity Server side configuration.

  • Step 6:

Start the server by running wso2server.sh or wso2server.bat

Now you should have to configure the client side accordingly. For an example i’m gonna explain how to do it with SoapUI.

SoapUI Side

  • Step 7:

Create new SoapUI project using any admin service to verify the functionality. In the following example i’m using ‘ServiceAdmin‘ to call operation ‘getWSDL‘. If you followed Step 5, you wsdl for ‘ServiceAdmin’ can be found at a location like https://localhost:9443/services/ServiceAdmin?wsdl

  • Step 8:

Configure SSL configurations in SoapUI Preferences as described in this blog post. Configuring ‘KeyStore‘ and ‘KeyStore Password‘ would be suffice to act SoapUI as a client. If you skipped Step 4 you would need to use <IS_Home>/repository/resources/security/wso2carbon.jks as the KeyStore and wso2carbon as the KeyStore Password.

  • Step 9:

Send sample request like following,

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://org.apache.axis2/xsd">
<soapenv:Header>
<m:UserName xmlns:m="http://mutualssl.carbon.wso2.org" soapenv:mustUnderstand="0">admin</m:UserName>
</soapenv:Header>
<soapenv:Body>
<xsd:getWSDL>
<!--Optional: -->
<xsd:serviceName>AuthenticationAdmin</xsd:serviceName>
</xsd:getWSDL>
</soapenv:Body>
</soapenv:Envelope>

As the response for above request you should get a response like following.

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
 <ns:getWSDLResponse xmlns:ns="http://org.apache.axis2/xsd">
 <ns:return>
 <ns1:getWSDLResponse xmlns:ns1="http://org.apache.axis2/xsd">
 <return>
 <wsdl:definitions targetNamespace="http://authentication.services.core.carbon.wso2.org" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" ....>
 <wsdl:documentation>AuthenticationAdmin</wsdl:documentation>
 ...
 </wsdl:definitions>
 </return>
 </ns1:getWSDLResponse>
 </ns:return>
 </ns:getWSDLResponse>
</soapenv:Body>
</soapenv:Envelope>
<span>

When the authentication happens it should done against certain user. To specify that user in this process, MutualSSLAuthenticator expects certain header in the soap envelop. Above soap request shows the example soap envelop with the said header which calls ServiceAdmin. Hence the changing the value of UserName property of the header would give you the control of the user needed to be authenticated.

Thats all.. 🙂

If you have any questions please drop a comment.

Fast track to add new mysql (secondary) user store in Identity Server 4.1.0

1. Setup a new database to use as new user store :

  • Open the terminal, go to dbscripts directory : cd <IS_Home>/dbscripts/
  • Open mysql command line as mysql admin : mysql -u adminusername -p
  • Enter your mysql admin’s password, then you’ll get mysql command line.
  • Run following commands for
    • Create new database to use as user store
    • Set new database as current database
    • Create UM tables
    • Set permission for a new mysql user
create database secondary_userstore_db;
use secondary_userstore_db;
source mysql.sql;
grant all on secondary_userstore_db.* TO connectuser@localhost identified by "connectpassword";
  • Exit from mysql command line : exit

2. Copy mysql connector (ex: mysql-connector-java-5.1.25-bin.jar) driver to <IS_Home>/repository/components/lib/ folder. Always check whether your MySQL Server is compatible with the connector you are using.

3. Add new datasource configuration to <IS_Home>/repository/conf/datasources/master-datasources.xml as follows,

        <datasource>
            <name>JDBC_USERSTORE_DB</name>
            <description>The datasource used for secondary user manager</description>
            <jndiConfig>
                <name>jdbc/SecondaryUMDB</name>
            </jndiConfig>
            <definition type="RDBMS">
                <configuration>
                    <url>jdbc:mysql://localhost:3306/secondary_userstore_db?DB_CLOSE_ON_EXIT=FALSE;LOCK_TIMEOUT=60000</url>
                    <username>connectuser</username>
                    <password>connectpassword</password>
                    <driverClassName>com.mysql.jdbc.Driver</driverClassName>
                    <maxActive>50</maxActive>
                    <maxWait>60000</maxWait>
                    <testOnBorrow>true</testOnBorrow>
                    <validationQuery>SELECT 1</validationQuery>
                    <validationInterval>30000</validationInterval>
                </configuration>
            </definition>
        </datasource>

4. Add new user store manager configuration in <IS_Home>/repository/conf/user-mgt.xml. Please note that here the order of <UserStoreManager> matters. The first <UserStoreManager> element in the file act as the primary user store. Since we want to add our new user store as a secondary, add following configuration after the existing <UserStoreManager> configuration.

        <UserStoreManager class="org.wso2.carbon.user.core.jdbc.JDBCUserStoreManager">
           <Property name="dataSource">jdbc/SecondaryUMDB</Property>
           <Property name="DomainName">SecondaryJDBC</Property>
           <Property name="ReadOnly">false</Property>
           <Property name="MaxUserNameListLength">100</Property>
           <Property name="IsEmailUserName">false</Property>
           <Property name="DomainCalculation">default</Property>
           <Property name="PasswordDigest">SHA-256</Property>
           <Property name="StoreSaltedPassword">true</Property>
           <Property name="UserNameUniqueAcrossTenants">false</Property>
           <Property name="PasswordJavaRegEx">^[\S]{5,30}$</Property>
           <Property name="PasswordJavaScriptRegEx">^[\\S]{5,30}$</Property>
           <Property name="UsernameJavaRegEx">^[^~!#$;%^*+={}\\|\\\\&lt;&gt;,\'\"]{3,30}$</Property>
           <Property name="UsernameJavaScriptRegEx">^[\\S]{3,30}$</Property>
           <Property name="RolenameJavaRegEx">^[^~!#$;%^*+={}\\|\\\\&lt;&gt;,\'\"]{3,30}$</Property>
           <Property name="RolenameJavaScriptRegEx">^[\\S]{3,30}$</Property>
           <Property name="UserRolesCacheEnabled">true</Property>
           <Property name="maxFailedLoginAttempt">0</Property>
        </UserStoreManager>

4. Start the server by running <IS_Home>/bin/wso2server.sh or (wso2server.bat).

Now you should be able to add users to new SecondaryJDBC user store and do other operations (like login to management console) using that users.

That’s it 🙂

Publishing log events to BAM

Recently I have been working on statistic publishing and auditing of WSO2 Identity Server and found this cool way to publish log events to WSO2 BAM. This method can be used in any carbon based product (of course which enabled logging feature :)) and it is inherited from this blog post.

What we going to do is publishing logging data into WSO2 BAM using a log4j appender. Logging feature includes org.wso2.carbon.logging.appender.LogEventAppender by default and it has capability to do our task.

First we download and unzip, WSO2 IS product (or any carbon based product) and open log4j.properties file. For WSO2 IS 4.5.0 onwards (carbon 4.2.0 onwards) this file is at <CARBON_HOME>/repository/conf/bundle-config/org.wso2.carbon.logging/ folder and for earlier versions it is at <CARBON_HOME>/repository/conf/ folder.

Now we should add our appender properties to log4j.properties file as follows,

# LOGEVENT is set to be a LogEventAppender using a PatternLayout to send logs to LOGEVENT
log4j.appender.LOGEVENT=org.wso2.carbon.logging.appender.LogEventAppender
log4j.appender.LOGEVENT.url=tcp://localhost:7611
log4j.appender.LOGEVENT.layout=org.wso2.carbon.utils.logging.TenantAwarePatternLayout
log4j.appender.LOGEVENT.columnList=%T,%S,%A,%d,%c,%p,%m,%I,%Stacktrace
log4j.appender.LOGEVENT.userName=admin
log4j.appender.LOGEVENT.password=admin
log4j.appender.LOGEVENT.processingLimit=1000
log4j.appender.LOGEVENT.maxTolerableConsecutiveFailure=20

Here in the second line we specifying a new appender called LOGEVENT which is a type of org.wso2.carbon.logging.appender.LogEventAppender. In the lines 3,6 and 7 it is specified that BAM thrift URL where our data needs to sent and BAM credentials which is needed to authenticate.

Now we have complete with defining our appender but we haven’t used yet. To do so, the new LOGEVENT appender should attached to a logger. For an example attaching to root logger can be done like this,

log4j.rootLogger=INFO, CARBON_CONSOLE, CARBON_LOGFILE, CARBON_MEMORY, LOGEVENT

But i’m not going to use root logger which is logging general logs, instead of that i’m going to use ‘log4j.logger.AUDIT_LOG’ which is only logging about specified as audit logs.

log4j.logger.AUDIT_LOG=INFO, AUDIT_LOGFILE, LOGEVENT

If we have the two servers on the same machine, then we have to set a port offset of one server to avoid port conflicts. Since we have already used default thrift port (7611) of BAM when configuring appender, i’m going to set port offset to my IS server by editing <CARBON_HOME>/repository/conf/carbon.xml file as follows,

<!-- Ports offset. This entry will set the value of the ports defined below to</pre>
the define value + Offset.
 e.g. Offset=2 and HTTPS port=9443 will set the effective HTTPS port to 9445
 -->
 <Offset>1</Offset>

Now all set. We have done the hard part. Now all we have to do is start the servers. First we need to start BAM server by running <BAM_HOME>/bin/wso2server.sh or <BAM_HOME>/bin/wso2server.bat according to your environment. Before starting the IS server we have to wait until the BAM start completely because if the BAM is unavailable, IS is trying to publish data to invalid URL.  Now start the IS by running <CARBON_HOME>/bin/wso2server.sh or using the bin as needed.

Now just play with the sever bit to generate few logs and you can see those published logs using the BAM cassandra explorer. The stream definition of published data also can be viewed from the cassandra explorer and these info can be used to further processing different methods such as individual hive scripts or complete toolbox.

Before to wrap up things these links will be useful if you are going into deep in different aspects.

[1] – Write custom appenders for log4j by Allen Holub

[2] – How to configure MT-Logging with WSO2 Products by Amani Soysa

[3] – Creating a Custom Toolbox

Thats it… 🙂

Project O’Lan – Prototype

I’ve created a prototype for the Project O’Lan and it succeeded…. Here is a snapshot of the result

Prototype image 01 for the Project O'Lan

In this picture, I have typed the sentence – hi this is working.

The first two words typed without transliteration, and second two words are transliterated form English-to-Russian.

Pretty fun huh….

Project Sinha-lisation

This is a WordPress plugin which I created for a part of my Level 3 project.

This plugin is for the users who are working with Sinhala language.

By using this a user can type in Sinhala without knowing Wijesekara or any other Sinhala keyboard. This plugin enabled web can converts from Sinahala phenoic(usually called as Singlish) to Sinahala unicode in any writable area, without requiring any other software for the user.

Simply this enables Singlish-to-Sinhala ability for any user, without any more requirements… 🙂