Tuesday, May 19, 2015

Setting up WSO2 Identity Server as the SAML2 Identity Provider for SimpleSAMLphp Service Provider [On Windows and WAMP]

SimpleSAMLphp is a web application written in native PHP that deals with authentication. This example shows how to configure the SimpleSAMLphp web application as a Service Provider with WSO2 Identity Server as the SAML2 Identity Provider. In this demonstration I am using the Identity Server 5.0.0 version with the Service Pack 1 installed.

First, let’s download the latest version of SimpleSAMLphp. At the time of this writing the latest version is 1.13.2. Once we download, we get simplesamlphp-1.13.2.tar.gz file. Extract this and you get simplesamlphp-1.13.2 directory. Rename the directory to simplesamlphp and copy to the web server. Here I have installed WAMP Server. I copy the simplesamlphp folder to the WAMP Server’s www directory which is located in C:\wamp\www path. Then I start the WAMP Server.

I can access the SimpleSAMLphp application now by visiting the following URL. (Note that the web pages of the application are located in the simplesamlphp/www directory and WAMP Server is running in port 80.


After visiting the above URL, it will automatically redirect to http://localhost/simplesamlphp/www/module.php/core/frontpage_welcome.php URL and you can see the welcome page.



Next step is to set the configurations related to the Service Provider and the Identity Provider.

I am adding the Service Provider configuration in simplesamlphp/authsources.php config file. (In the deployed web app, C:\wamp\www\simplesamlphp\config\authsources.php)

Add the following configuration to the file and save. Here the SAML Issuer is given in entityID and the Identity Provider URL is given in idp property.
    'wso2-sp' => array(  
  
        'saml:SP',  
          
        // The entity ID of this SP.  
          
        // Can be NULL/unset, in which case an entity ID is generated based on the metadata URL.  
          
        'entityID' => 'simplesaml',  
          
        // The entity ID of the IdP this should SP should contact.  
          
        // Can be NULL/unset, in which case the user will be shown a list of available IdPs.  
          
        'idp' => 'https://localhost:9443/samlsso',  
          
        // The URL to the discovery service.  
          
        // Can be NULL/unset, in which case a builtin discovery service will be used.  
          
        'discoURL' => NULL,  
          
    ),


Next step is to add the Identity Provider metadata configuration in the simplesamlphp/metadata/saml20-idp-remote.php config file. (In the deployed web app,
C:\wamp\www\simplesamlphp\metadata\saml20-idp-remote.php)

$metadata['https://localhost:9443/samlsso'] = array(  
  
   'name' => array(  
  
   'en' =>  'WSO2 IS',  
  
   'no' =>  'WSO2 IS',  
  
),  
  
   'description'   =>  'Login with WSO2 IS SAML2 IdP.',  
  
   'SingleSignOnService'  =>  'https://localhost:9443/samlsso',  
  
   'SingleLogoutService'  => 'https://localhost:9443/samlsso',

  'certFingerprint'      => '6bf8e136eb36d4a56ea05c7ae4b9a45b63bf975d'
);

A detailed description on the above IDP remote metadata is available in [1].

Note that metadata ['https://localhost:9443/samlsso'] should match value of 'idp' in simplesamlphp/authsources.php service provider configuration.

6bf8e136eb36d4a56ea05c7ae4b9a45b63bf975d is the thumbprint of the default certificate ships with WSO2 IS. SAML2 Response/Assertion is signed with this certificate by default.

You can find these configuration files in [2] for further reference.

Next step is to configure the Identity Server. Start the Identity Server and login to the management console as admin.

First we need to set the IDP Entity ID of the SAML2 configuration in Resident IDP of Identity Server to the URL of SAML endpoint of IS. Go to Main -> Identity Providers -> List  and click on Resident Identity Provider


Expand the Inbound Authentication Configuration menu and then SAML2 Web SSO Configuration. Set the Identity Provider Entity Id value to the SAML endpoint URL of IS. By default this is https://localhost:9443/samlsso when you run IS with port offset 0. Then Update the configuration.


Next step is to create a Service Provider in IS. Go to Main -> Service Providers -> Add. For the Service Provider name you can specify any name. Here I’m giving the name as simplesaml.


Once the Service Provider is registered, Edit the configuration.


Expand the Inbound Authentication Configuration and SAML2 Web SSO Configuration. Click on Configure link.


Following are the values we have to specify.



Note that as the Issuer name we have to give the same name set in the Service Provider configuration in SimpleSAMLphp web app. Set the other configuration as shown below and Register.


Update the Service Provider once the SAML2 issuer is successfully added.


Now we can test the SimpleSAMLphp web application. Open the application in browser (i.e http://localhost/simplesamlphp/www ) and select Authentication tab. Click on Test configured authentication sources link.

Now you see the wso2-sp which was previously added in Service Provider configuration. Click on the wso2-sp link.


It will redirect to the login page of the Identity Server. Here I login as admin.


Now I am successfully authenticated to the SimpleSAMLphp application using the WSO2 Identity Server as the Identity Provider.


If you want to test this further, you can follow the following steps which shows how to retrieve claims of the logged in user.

Here I add a new user in the Identity Server.


I enter the username and password for the new user and click Next.


For demonstration purpose I assign the admin role to this user.


Once the user is created I edit the User Profile.


The user profile attributes are set for the user.


Now I need to select which claims/attributes should be sent to the SimpleSAMLphp application when a user is authenticated. For that, Edit the configuration of the simplesaml Service Provider.


Expand the Claim Configuration menu in the Service Provider configuration.  



As the Subject Claim URI, select http://wso2.org/claims/givenname because that is the claim which identifies a user uniquely.  Under the Requested Claims I add several claims where I added values in the user profile of the created user. Then Update the Service Provider configuration.


Now again try to login to the SimpleSAMLphp application with wso2-sp Service Provider.


Now in the login page of the Identity Server I enter the credentials of the newly created user.

Upon successful authentication I can see the requested claim attributes are successfully received.



References :

Tharindu Edirisinghe
Identity Server Team
WSO2

Monday, May 11, 2015

Cross-Database Programming Tips for WSO2 Developers - When Not to Use 'NOT NULL' Constraint

WSO2 products are supporting different types of databases by design. When considering a product like WSO2 Identity Server, you can use a database like Oracle, Microsoft SQL Server, MySQL, IBM DB2, PostgreSQL etc. according to your requirements. You can even use a combination of  databases (i.e as the PRIMARY userstore you may use Oracle and as a Seconday userstore you may use MS SQL Server for storing users).

However when you are writing code that deals with databases, it is really important that your code supports whatever the underlying database used. In this post I will show when not to use NOT NULL constraint.

Here I’m creating a simple table with the name PROJECTS that has three columns ID, NAME and LOCATION. ID is the PRIMARY KEY of the table which cannot be NULL at any occasion. Additionally I define NAME and LOCATION columns also with NOT NULL constraint. Then I insert one row that has values for all the three columns.

CREATE TABLE PROJECTS
(
 ID INT PRIMARY KEY,
 NAME VARCHAR(30) NOT NULL,
 LOCATION VARCHAR(20) NOT NULL
);

INSERT INTO PROJECTS(ID, NAME, LOCATION) VALUES (1, 'WSO2 IDENTITY SERVER', 'SRI LANKA');


I can see the record is successfully inserted into the table.


Now I want to insert another record where I know the values for the ID and NAME columns. Assume that the LOCATION of the project is not known.

INSERT INTO PROJECTS(ID, NAME) VALUES (2, 'WSO2 ESB');

In Oracle database it gives the following error.

SQL Error: ORA-01400: cannot insert NULL into ("ORCL"."PROJECTS"."LOCATION")
01400. 00000 -  "cannot insert NULL into (%s)"
*Cause:    
*Action:


Now for the LOCATION column I try to insert an empty string in the Oracle database.

INSERT INTO PROJECTS(ID, NAME, LOCATION) VALUES (2, 'WSO2 ESB', '');

But Oracle gives the following error.

SQL Error: ORA-01400: cannot insert NULL into ("IDHWPROD"."PROJECTS"."LOCATION")
01400. 00000 -  "cannot insert NULL into (%s)"
*Cause:    
*Action:


This is because Oracle database treats an empty string as a NULL value [1]. Since we have a NOT NULL constraint defined on the LOCATION column, in Oracle database we cannot insert a record unless we insert a dummy value to the column with the NOT NULL constraint. This dummy value can be a string that has a space (i.e ‘ ‘).

If we try the same with MySQL it works perfectly where MySQL does not treat empty strings as NULL.

Therefore when defining a table, you have to use the NOT NULL constraint only if it is really needed. If you have a column with NOT NULL constraint, and if you have to insert a record to the table where you do not have a value for that column, you will face this problem if you have the Oracle database. A simple solution would be to send a string with the value of a space but then you have to make sure that you do not trim the string before inserting to the table.

WSO2 Identity Server 5.0.0 has a similar issue (reported in [2]) with IDN_IDENTITY_USER_DATA table where the DATA_VALUE column has the NOT NULL constraint defined. With this, we cannot insert a record to the table if we do not know the value for this column when using an Oracle database. From the code it inserts a record to the table, the value is trimmed to remove unnecessary white spaces from the beginning and the end of the string. Therefore we simply cannot insert a space as a dummy value which will ultimately be converted to an empty string and to a NULL value at the database level of Oracle.

CREATE TABLE IDN_IDENTITY_USER_DATA
(
   TENANT_ID INTEGER DEFAULT -1234,
   USER_NAME VARCHAR(255) NOT NULL,
   DATA_KEY VARCHAR(255) NOT NULL,
   DATA_VALUE VARCHAR(255) NOT NULL,
   PRIMARY KEY (TENANT_ID, USER_NAME, DATA_KEY)
)

If you have an Identity Server running where the tables in the database are already created, you have no option other than dropping the NOT NULL constraint from the table for the DATA_VALUE column as below.

ALTER TABLE IDN_IDENTITY_USER_DATA MODIFY (DATA_VALUE NULL);

Therefore from the next release of the Identity Server IDN_IDENTITY_USER_DATA table’s DATA_VALUE column will not have the NOT NULL constraint for supporting all the databases including Oracle.

References


Tharindu Edirisinghe
Identity Server Team
WSO2