SSO Between WSO2 Servers - 8 Easy Steps

Follow these 8 easy steps to configure SAML2 Single Sign On between multiple WSO2 servers. Here I’ll be using Identity Server 4.6.0 and Application Server 5.2.1. You can add multiple servers such as ESB, DSS and so on. This assumes you’re running each server with a port offset on a single machine. You can leave Identity Server port offset untouched so it’ll be running on 9443 by default. Go to <WSO2_SERVER>/repository/conf/carbon.xml and increase the <Offset> by one for each server.

First of all we’re going to share governance registry space between multiple servers. This way, when you create a tenant, information such as the keystores that’s generated for that tenant will be accessible across multiple servers.

Step 1 - Creating databases

1
2
3
4
5
mysql> create database ssotestregistrydb;
Query OK, 1 row affected (0.00 sec)

mysql> create database ssotestuserdb;
Query OK, 1 row affected (0.00 sec)

Step 2 - Create DB schema

Create the schema for this using <WSO2_SERVER>/dbscripts/mysql.sql

1
2
$ mysql -u root -p ssotestregistrydb < wso2as-5.2.1/dbscripts/mysql.sql
$ mysql -u root -p ssotestuserdb < wso2as-5.2.1/dbscripts/mysql.sql

Note that it’s the same schema for both databases. This is because the database script have table definitions for both registry and user management. Later on you can create only registry related tables (starts with prefix REG_) and user management related tables (starts with UM_) when you do a production deployment.

Step 3 - Adding newly created DBs as data sources

Open <WSO2_IS>/repository/conf/datasources/master-datasources.xml and add configs for Registry and user mgt. Put the same 2 data sources to <WSO2_AS>/repository/conf/datasources/master-datasources.xml as well.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<datasource>
    <name>WSO2_CARBON_DB_REGISTRY</name>
    <description>The datasource used for registry and user manager</description>
    <jndiConfig>
        <name>jdbc/WSO2CarbonDBRegistry</name>
    </jndiConfig>
    <definition type="RDBMS">
        <configuration>
            <url>jdbc:mysql://localhost:3306/ssotestregistrydb</url>
            <username>root</username>
            <password>root</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>

<datasource>
    <name>WSO2_CARBON_DB_USERMGT</name>
    <description>The datasource used for registry and user manager</description>
    <jndiConfig>
        <name>jdbc/WSO2CarbonDBUserMgt</name>
    </jndiConfig>
    <definition type="RDBMS">
        <configuration>
            <url>jdbc:mysql://localhost:3306/ssotestuserdb</url>
            <username>root</username>
            <password>root</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>

Make sure to copy MySQL JDBC driver to all WSO2 servers <WSO2_SERVER>/repository/components/lib

Step 4 - Change user management DB

In both Identity Server and Application Server, open up <WSO2_SERVER>/repository/conf/user-mgt.xml,

1
2
3
4
5
6
7
8
9
10
<Configuration>
<AddAdmin>true</AddAdmin>
        <AdminRole>admin</AdminRole>
        <AdminUser>
             <UserName>admin</UserName>
             <Password>admin</Password>
        </AdminUser>
    <EveryOneRoleName>everyone</EveryOneRoleName>
    <Property name="dataSource">jdbc/WSO2CarbonDBUserMgt</Property>
</Configuration>

Step 5 - LDAP configuration

Copy the LDAP config from <WSO2_IS>/repository/conf/user-mgt.xml, change the LDAP host/port and put it to <WSO2_AS>/repository/conf/user-mgt.xml. Comment out JDBC user store manager from AS user-mgt.xml. This way, we’re pointing Application Server to the embedded LDAP user store that comes with Identity Server. This will act as the user store in this setup. Why you need a separate relational data store? While LDAP will hold all the user and roles, MySQL DB will have all permissions related to users and roles.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<UserStoreManager class="org.wso2.carbon.user.core.ldap.ReadWriteLDAPUserStoreManager">
    <Property name="TenantManager">org.wso2.carbon.user.core.tenant.CommonHybridLDAPTenantManager</Property>
    <Property name="defaultRealmName">WSO2.ORG</Property>
    <Property name="kdcEnabled">false</Property>
    <Property name="Disabled">false</Property>
    <Property name="ConnectionURL">ldap://localhost:10389</Property>
    <Property name="ConnectionName">uid=admin,ou=system</Property>
    <Property name="ConnectionPassword">admin</Property>
    <Property name="passwordHashMethod">SHA</Property>
    <Property name="UserNameListFilter">(objectClass=person)</Property>
    <Property name="UserEntryObjectClass">identityPerson</Property>
    <Property name="UserSearchBase">ou=Users,dc=wso2,dc=org</Property>
    <Property name="UserNameSearchFilter">(&amp;(objectClass=person)(uid=?))</Property>
    <Property name="UserNameAttribute">uid</Property>
    <Property name="PasswordJavaScriptRegEx">^[\S]{5,30}$</Property>
    <Property name="ServicePasswordJavaRegEx">^[\\S]{5,30}$</Property>
    <Property name="ServiceNameJavaRegEx">^[\\S]{2,30}/[\\S]{2,30}$</Property>
    <Property name="UsernameJavaScriptRegEx">^[\S]{3,30}$</Property>
    <Property name="UsernameJavaRegEx">[a-zA-Z0-9._-|//]{3,30}$</Property>
    <Property name="RolenameJavaScriptRegEx">^[\S]{3,30}$</Property>
    <Property name="RolenameJavaRegEx">[a-zA-Z0-9._-|//]{3,30}$</Property>
    <Property name="ReadGroups">true</Property>
    <Property name="WriteGroups">true</Property>
    <Property name="EmptyRolesAllowed">true</Property>
    <Property name="GroupSearchBase">ou=Groups,dc=wso2,dc=org</Property>
    <Property name="GroupNameListFilter">(objectClass=groupOfNames)</Property>
    <Property name="GroupEntryObjectClass">groupOfNames</Property>
    <Property name="GroupNameSearchFilter">(&amp;(objectClass=groupOfNames)(cn=?))</Property>
    <Property name="GroupNameAttribute">cn</Property>
    <Property name="SharedGroupNameAttribute">cn</Property>
    <Property name="SharedGroupSearchBase">ou=SharedGroups,dc=wso2,dc=org</Property>
    <Property name="SharedGroupEntryObjectClass">groupOfNames</Property>
    <Property name="SharedGroupNameListFilter">(objectClass=groupOfNames)</Property>
    <Property name="SharedGroupNameSearchFilter">(&amp;(objectClass=groupOfNames)(cn=?))</Property>
    <Property name="SharedTenantNameListFilter">(objectClass=organizationalUnit)</Property>
    <Property name="SharedTenantNameAttribute">ou</Property>
    <Property name="SharedTenantObjectClass">organizationalUnit</Property>
    <Property name="MembershipAttribute">member</Property>
    <Property name="UserRolesCacheEnabled">true</Property>
    <Property name="UserDNPattern">uid={0},ou=Users,dc=wso2,dc=org</Property>
    <Property name="RoleDNPattern">cn={0},ou=Groups,dc=wso2,dc=org</Property>
    <Property name="SCIMEnabled">true</Property>
    <Property name="MaxRoleNameListLength">100</Property>
    <Property name="MaxUserNameListLength">100</Property>
</UserStoreManager>

Step 6 - Mount governance registry space

This configuration share the governance registry space between WSO2 servers. Having a common governance registry space is mandatory when you create tenants because tenant specific keystores are written and kept in registry.

In <WSO2_IS>/repository/conf/registry.xml,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<dbConfig name="wso2registry_gov">
    <dataSource>jdbc/WSO2CarbonDBRegistry</dataSource>
</dbConfig>

...

<remoteInstance url="https://localhost:9443/registry">
    <id>govregistry</id>
    <dbConfig>wso2registry_gov</dbConfig>
    <readOnly>false</readOnly>
    <enableCache>true</enableCache>
    <registryRoot>/</registryRoot>
</remoteInstance>

<mount path="/_system/governance" overwrite="true">
    <instanceId>govregistry</instanceId>
    <targetPath>/_system/governance</targetPath>
</mount>

Add the same configuration to <WSO2_AS>/repository/conf/registry.xml as well. So the Application Server is also pointing to the same governance space.

Step 7 - Install SSO management feature in Identity Server

Start Identity Server, login as admin/admin and go to Configure -> Features. Add a new repository.

Repo URL - http://dist.wso2.org/p2/carbon/releases/turing/

Uncheck “Group features by category” checkbox

Seach by features with the string “stratos”

Select “Stratos - Stratos SSO Management - 2.2.0” feature and install it. Click Finish. Restart Identity Server

Step 8 - Create SSO IdP configuration

Create the file - <WSO2_IS>/repository/conf/sso-idp-config.xml following should be the content,

1
2
3
4
5
6
7
8
9
10
<SSOIdentityProviderConfig>
    <ServiceProviders>
        <ServiceProvider>
            <Issuer>carbonServer</Issuer>
            <AssertionConsumerService>https://localhost:9444/acs</AssertionConsumerService>
            <SignResponse>true</SignResponse>
            <EnableAttributeProfile>true</EnableAttributeProfile>
        </ServiceProvider>
    </ServiceProviders>
</SSOIdentityProviderConfig>

You should have a <ServiceProvider>…</ServiceProvider> config for each WSO2 server you’re using

You can test SSO by logging into Identity Server as admin/admin (this is the super user) and creating a new tenant by going to Configure -> Add New Tenant. Then try to login to Application Server. You’ll be redirected to Identity Server login page. Now login as the tenant admin user you just created. If you want to add additional servers like ESB, DSS all you have to do is get the same configuration you did for Application Server here. Replace with the correct port and the Issuer.

Things to Know Before Moving

Moving can be easy or very stressful depending on when and how you do it. These are somethings I wish I knew before. I’m jotting them down incase it might be useful for someone.

First thing you have to do when you move is to get a local telephone number if you don’t have one already. I didn’t believe the importance of having a telephone until I walked down the path of getting different things setup. Things like cable/internet, electricity are easily looked up from the phone number (and address too of course). Phones with multi-year contracts are a thing of the past. Most carriers sell sim cards with prepaid/post paid plans which are very easy to move/upgrade later if you’re unsatisfied or want to move to a plan with more minutes/data.

As soon as you get a phone the next thing is to apply for a social security number. Social security number is important for getting salary/medical insurance docs sorted. Usually the office opens at 9am. Going around 8.45am would be ideal. I had to come back 3 times because there were so many people and a lot of waiting time. Social security takes about 2 weeks to come by mail.

Opening a bank account is the next important thing. The bank I chose to do banking with required to have social security in order to open an account. There might be banks that doesn’t require having an SSN so please look around for that. If you cannot open an account that means you’ll have to wait at least 2 weeks to get it done because of the SSN. This created a bunch of headaches for me so you’re better off choosing a bank that doesn’t require having an SSN at first and may be move later.

Having done all that then finding a place to stay is the most challenging. There are tens of neighborhoods to choose from. An easy rule of thumb to follow is finding a place near the work place. There are many factors to consider and everyone has their set of preferences like whether you want city life, amenities, security, crime rate, shops and so on. There are many sites out there that let you search on different neighborhoods as well as on specific price ranges. Having local friends who’s been living nearby for sometime can give valuable advice too. Once you find a place then you have to keep a security deposit and the first month’s rent as the movein charge. This, in most places have to come in as a chashiers cheque or a money order. You can’t get a cashiers cheque without having a bank account. So if you’re in a hurry to find a place then better to have a bank account somewhere. When you get a place and sign the lease, usually 12 months (can be less depending on the property and location) if you have to move out before the lease end period, a lease break fee will be charged and it’s HUGE (in some cases). So make sure to ask that in advance if possible. Also when you move out (if it’s an apartment) they’ll be charging you for carpets/paints/doors/windows/washrooms for their condition and state. Depending on the condition it’s going to be several hundred dollars, even if it “looks almost new” and you’ve barely used them or was in that place for a short time. So discussing these in advance and being ready for those helps.

When you first come, you’ll have to arrange some transportation to go around places. Once you’re ready to get a vehicle for a longer term, there are many options. There are many different car dealers and even if you’re a seasoned car buyer, chances of getting caught up in scammers the car dealers put through is very high. Dealers get a sense of who you are just by looking at you and will try to get more money out of you. When you’re in a dealership and your see something you like then from that point on you have to be extra careful. Even though they ask your information to show around doesn’t mean you have to buy it immediatly agreeing to whatever they say. You can walk away until you put your signature down in a lease. Here, again whether you want to buy or lease depends on your requirements. Remember that when you lease, there’s a cap for miles you can drive the car on an yearly basis. Starts from about 10k miles and increment in 2.5k miles or so. When you want to drive more miles your monthly premium will go up. So if you’re in for the long haul buying will be a cheaper option. Don’t forget to do your homework by going to many sites out there which gives you valuable information about leasing/buying, which car to get, cost of ownership, gas, maintenance etc… Also importantly look for ratings/reviews of a dealership before.

Medical insurance is another critical thing that to get sorted. When you’re in an unknown place how to get medical help is very valuable info. Here ofcourse without medical insurance it can be hell. I’ve been to an emergency care facility where we were politely asked to go elsewhere middle of the night because at that time we didn’t have medical insurance. You walk into an emergency care because it’s a fucking emergency. Later that day we found a place where they treated us so well without any questions or fuss. Anyway, have the medical sorted ASAP. If you’re asked to choose a medical plan that can be very hard and tricky. When you think about it, it’s all easy you think how can something as cut and dry as this will be so difficult. One problem that I had to deal with is insurance brokers don’t tell you what you need to know. It’s almost as if they’re trying to make it deliberately complex and the plans and the literature around that is so complex and convoluted to follow. If you have just one option then all is easy.

When you have to move states then some of these you have to do all over again. States differ in salary/taxes and even little things around how get a house/apartment. When you have to do that it’s better to carry all of your docs with you because you don’t know what documents people might be asking. I had to get a social security confirmation letter which as I heard later, is going to be phased out soon. It’s better to ask the house/apartment people in advance what sort of documents you have to submit and prepare for that so it’s one less hassel.

Selecting a Strategy for New IT

There are many advantage that you can gain from moving to new IT that connects business data with customers, partners and general public in general. “New IT” here refers to pretty much any process/mechanisms that you take to move away from siloed applications and having a more integrated experience to make day to day business more efficient. From a business and project management standpoint this can mean gaining more visibility into ongoing projects and the business impact they make. From an engineering stand point this can mean, versions of each project that’s in production, projects that will be going to production soon, critical bugs affecting a release schedule and so forth. This blog tries to explore couple of existing problems and how API management helps to move forward with adopting “new IT” for a connected business.

Existing processes

Everyone has some sort of a process/methodology that works for them. No 2 places or teams are alike. When there are already systems and certain ways of doing things are in place, it’s hard to introduce change. First and foremost the battle seems to be from the developers who are accustomed to doing certain things in certain ways. When introducing something that’s new, it’s always helpful to position it as filling a gap in the current process, doing incremental improvements.

Possible problems

Let’s see what some of the usual problems and how API management can solve those.

Standard method for writing services

If you have a rigid standard when introducing a new service, that might not be optimal. Rigid standards in the sense that tied to particular architectural style like REST or everything being a SOAP service. There are some services and scenarios where a SOAP service make sense and there are other situations where an HTTP service accepting a JSON message would be much simple and efficient. Having a one true standard which forces non-optimal creation of services will lead to unhappy developers/consumers and end up not being reused at all.

Challenges in service versioning/consistent interfaces

When a new version of a service is to be released, there has to be a way of versioning the service. If you can disrupt all the client and force them to upgrade then that’s easy (in case of an API change). Otherwise there has to be a way of deprecating an exising service and moving it to the new one.

Finding an existing service. Encouraging service reuse

If there are services available, then there should be a way to discover existing services. Not having a place to discover existing services is going to make service reuse a nightmare. This is not about holy grail of service reuse most SOA literature talks about. Think about how a developer in another team or a new hire discover services.

Monitoring/Metering/Throttling

When you have a service, you need to find out who’s using that service, what are the usage patterns, should certain clients be throtted out to give priority for other clients and so on. If you don’t have any metering, it’s near impossible to determine what’s going on. Problems (if you have any) service consumers face. It also helps to have historic data for doing projections that’ll result in resources expansions accordingly.

Solution

Here I would like to present a solution and how it will address some of the problems we listed out earlier. Make APIs the interfaces for services. There is a difference between a service and an API. API will be the consistent interface to everything outside (users within the organization/partners/suppliers/customers etc…), anything or anyone who will consume the service.

Having an API fa├žade will be the first step. You can expose a SOAP based service without any problem. Exposing a REST service falls naturally. Exposing a service is not bound by any imposed standard anymore. A service can be written by analysing the best approach based on the problem at hand.

Versioning is enabled at the service definition level. The API layer. Following picture shows how to create a new version of an existing API.

In the picture above it shows the current API version in the top and you can give a version when you’re creating the new one. Once you create the API, at the publishing stage you can choose whether to deprecate the existing API or to have them coexist so that the new version is taken as a separate API. As following picture shows,

Another cool thing is that you can choose whether to revoke existing security tokens, forcing all clients no re-subscribe.

Next up is having a place for developers to find out about existing services. API Manager has a web application named API Store that list out published APIs. Here’s an example for the store that’s developed on top of API Manager. Monitoring is equally simple and powerful.

This is how API Manager helps to make life easy as well as help making the right technical choice. Allowing developers and other stakeholders to choose right service type, message formats encouraging service implementation to be diverse but still, having a consistent interface where monitoring/security/versioning etc… can be applied with ease.

Implementing an SOA Reference Architecture

A reference architecture try to capture best practices and common knowledge for a particular subject area or a business vertical. Although you can define a reference architecture at any level, for the purpose of this blog we’ll be talking about an SOA reference architecture. When tasked with implementing an SOA architecture, blindly folloing a reference architecture might not give optimal results. If business requirements are not considered sometimes it will be not the right fit for the issues at hand.

When an SOA architecture is going to be implemented, close attention should be given to business requirements and any other technological constraints. Having to work with a specific ERP system, having to work with a legacy datastore which otherwise, too expensive to replace with a whole new system and so on. Based on these facts a solution architecture should be developed that’s aligned with the business requirements.

Looking at the solution architecture a toolset should be evaluated that maximize ROI and possible future enhancements that might come in the next 1 - 2 years. Evaluating an existing architecture every 1 - 2 years and making small refinements saves the time and effort for doing big bang replacements and modifications for critical components. While selecting a toolset having a complete unified platform helps to build the bits you need right away and still have room for additions later. If you’re looking for a complete platform you probably want to consider WSO2 middleware platform provide a complete open source solution.

I’m biased for open source solutions and having a platform that makes connected business possible is mighty cool.

Twitter Scale

High scalability has a great blog about architecture of Twitter. How Twitter grew up from just a web application to handle thousands of tweets and the internal architecture of components they have. Last week I wrote a blog about how a simple web application might evolve according to different requirements with time and how it will save you a lot of time to come up with a loosely coupled architecture between your componets and how it would help immensely when it comes to handle difficult problems. Above article is a wonderful real life example of how Twitter evolved to handle massive number of users and tweets. Twitter is all about posting messages that are only 140 characters long. How hard can it be to write a webpage to handle that?! Great example how simple things can yield to a complex architecture on the backend to give a responsive user experience.

The article has a lot of details about problems specific to Twitter and tweets. Couple of big picture points I want to highlight are (straight from High Scalability article),

  • Twitter no longer wants to be a web app. Twitter wants to be a set of APIs that power mobile clients worldwide, acting as one of the largest real-time event busses on the planet.
  • Internal clients use roughly the same API as external clients.
  • 1+ millions apps are registered against 3rd party APIs
  • Tweets are forked off in many different ways, mostly to decouple teams from each other. The search, push, interest email, and home timeline teams can work independently of each other.
  • For performance reasons the system has been being decoupled.

Read the original article.