Menus

Monday, June 20, 2016

Custom processor with new Identity Framework IS 5.3.0

In the current authentication framework (upto IS 5.1.0), we had endpoints for each type of request. As an example we had samlsso endpoint (https://localhost:9443/samlsso) to handle samlsso requests, oauth endpoint for oauth (https://localhost:9443/oauth) etc. So we had servlets in the endpoint hosted, waiting to receive those requests. But at each servlet we did few common things. The current SAMLSSOProviderServlet can be found at [1]. There, all the logic is written through the handleRequest() method. From the work done here we can identify two kind of necessary work in the flow. 
  1. Unique workload needed in SAML flow
    • SAML request validation
    • DTO, DO and DAO preparation
    • SAML response building
  2. Common workload for every endpoint.
    • Building authentication request
    • Sending request to frameowrk for login, logout etc
    • Handling response form framework after login and logout
It is obvious, implementing common-things at every endpoint is unnecessary. There fore the IS team has come up with a new framework which will give the facility to develop custom "endpoints" (processors) easier than before. Actually there is no more endpoints for different requests. These servlets will be replace by "processors" which is equivalent to old servlets.

Ok lets see what is new in the authentication framework. In new Identity Server there is no multiple endpoints. Only endpoint is "identity" endpoint, https://localhost:9443/identity. Lets see how we are going to replace the "samlsso" endpoint with the new processor (with "identity endpoint"). The code for new SAML endpoint can be found at [2].

We will use travelocity.com [3] for example. The flow in the current implementation using SAML endpoint is as follows. The same should happen in the new implementation also.



Everything above was handled starting from a dedicated servlet called 'SAMLSSOProviderServlet'. In the travelocity.properties "SAML2.IdPURL" is set to value "https://localhost:9443/samlsso." Now it should be set to "https://localhost:9443/identity". So the IdentityServlet will receive the request. But it doesn't know how to handle this request. Starting from there everything above should be implemented by us. For that we need to understand the flow in current Identity Servlet.

Now we can easily look at how we are going to replace the SAMLSSOProviderServlet with IdentityServlet, using the Factory and Builder pattern introduced into new framework in IS 5.3.0.

The HTTPIdentityRequestFactory, HTTPResponseFactory, IdentityProcessor should be registered in the OSGI context. All these three entities has a method "canhandle", which will decide whether the respective entity can handle the given scenario. In Identity Framework all of these will be stored in a respective list and this list will be iterated in the order of priority and the method "canhandle" will be called.


We should build an SAMLIdentityRequest object which includes the necessary parameters and functionalities using the HTTPServletRequest. For that we need an SAMLIdentityRequest.SAMLIdentityRequestBuilder. For that we need an SAMLIdentityRequestFactory. [4] Following methods should be implemented in order to cooperate with the framework.

Methods to be implemented in SAMLIdentityRequestFactory 

canhandle

Check whether the HttpServletRequest is a SAML request. Here simply we have checked whether the request has a query parameter "SAMLRequest"

getPriority

The priority of the RequestFactory decides the index in the HTTPIdentityRequestFactory list, which is added to OSGI context throughout all the components. We have given a high priority to ake it sure that other RequestFactory is not picked before our SAMLIdentityRequestFactory. If a wrong factory is picked up it will end upwith a runtime exception.

create

This should create the SAMLIdentityRequestBuilder with the needed properties assigned.

handleException

Decides how the exception should be handled and send the HTTPResponseBuilder. Here we can decide whether ti be redirected to another location etc. things.



As you can see in the sequence diagram, all the builders are inner classes in the respective entity. I.E IdentityRequestBuilder is an inner class of IdentityRequest. Hence our SAMLIdentityRequestBuilder is also an inner class of SAMLIdentityRequest. Both are extended respectively from IdentityRequest.IdentityRequestBuilder and IdentityRequest.


Both have the same properties while SAMLIdentityRequest has getters and SAMLIdentityRequestBuilder has setters. So all the properties should be initialized in the time of creating IdentityRequestBuilder.

IdentityRequest object keeps the necessary parameters in the first HTTPServletRequest. This is stored in the cache context. 

Does this cause data redundancy and spend space twice? No. Only the reference is used in the SAMLIdentityRequest constructor.

Now we have built the IdentityRequest. Now we should process the IdentityRequest. For that we need an processor extended from IdentityProcessor. Now this proccessor will validate the SAML Request and if successfully validated, will return the FrameworkLoginResponse.FrameworkLoginResponseBuilder which will the sp to identify whether user is already authenticated or not. If not it will be redirected to the authentication endpoint via the commanauth endpoint.

Everything is handled in abstract IdentityProcessor "buildResponseForFrameworkLogin". We just need to call that method with an IdentityContext which includes the IdentityRequest we built.

Methods to be implemented in SPInitSSOAuthnRequestProcessor

canHandle

Just as in the RequestFactory, here we should decide whether the given IdentityReuest can be processed in this processor. As we have a custom IdentityRequest we can just check whether the IdentityRequest is an "instanceof" SAMLIdentityRequest.

getRelyingPartyId

This is used in the "buildResponseForFrameworkLogin" and "buildResponseForFrameworkLogout" methods. Here we have assigned the relyingParty sent in the request, if there is one.

getName

This will be also  used in above methods as the "type". Simply assigned the class name for the name.

getPriority

The priority of the IdentityProcessor decides the index in the IdentityProcessor list, which is added to OSGI context throughout all the components. We have given a high priority to ake it sure that other IdentityProcessor is not picked before our SPInitSSOAuthnRequestProcessor. If a wrong factory is picked up it will end upwith a runtime exception.

getCallbackPath

Callbackpath is the url, which the SP should be redirected upon completion of authentication at commonauth endpoint.

process

The processing functionality. In this processor basically we have validated the SAML request.  All the process methods should return a IdentityResponse.IdenstityResponse builder. Here we will return an default FarameworkLoginResponseBuilder which is returned from the "buildResponseForFrameworkLogin". For this to call we need an IdentityMessageContext. This object includes the IdentityRequest we built. This context will be cached in the framework. Here we have created a custom SAMLMessageContext. In this object you can include other fields which you need access later. The only thing is they should be serializable, as this is going to be cached.





After this processor is executed the user will be redirected to the authentication endpoint if he is not already authenticated, or to the IdentitySevlet if the user is authenticated, with the "sessionDataKey". To handle this we have implemented SSOLoginProcessor. 


References

Friday, March 18, 2016

Know the last login time and last password updated time in IS 5.2.0

These are the new features which are going to be introduced with IS 5.2.0.

It is really very simple to get the last login time and last password updated time with WSO2 IS 5.2.0.
  • Down the IS server if you have already running.
  • Open <IS-HOME>/repository/conf/identity/identity.xml. Enable the IdentityMgtEventListener under <EventListeners> with following. 

<EventListener type="org.wso2.carbon.user.core.listener.UserOperationEventListener" name="org.wso2.carbon.identity.mgt.IdentityMgtEventListener" orderId="50" enable="true"/>

  • Start the IS server. 
  • Go to Claims List in the management console. 
  • Select http://wso2.org/claims 
  • Exapnd Last Login claim and select edit. Check support by default option under it. Update the settings by clicking update.
  • Exapnd Last Password Update claim and select edit. Check support by default option under it. Update the settings by clicking update.
Now you should be able to see these values listed in the user profile. To check the user profile go to Users and Roles list. Select Users. Select User Profile of the user you want to check. You should be able to see the Last Login and Last Password Update time stamps. 

Sunday, December 6, 2015

Configure Salesforce as a SAML SSO service provider in WSO2 Identity Server 5.1.0

Salesforce can be used as a service provider in the WSO2 Identity Server. That means saleforce can be configured so that users are redirected to WSO2 Identity Server for authentication when they login. So the authentication process is done by Identity Server. This post will show you the necessary settings to set salesforce as a service provider in Identity Server using SAML SSO.

Settings at salesforce side.
  1. Go to Salesforce developer console and create an account. You will get a email to your email address to verify.
  2. Go to salesforce login and login. Check whether you are at developer console. If not click the drop down (down arrow) next to your user name at top right corner and select "Developer Console"
  3. Developer Console
  4. On the left panel, under "Administrator", click Domain Managment >>  My Domain. Create a new domain giving a domain id. It will take sometime to get the approval for the domain. You will receive a email within maximum of 15 minuets. 
  5. On the left panel, under "Security Controls", (above "Administrator"), click Single Sign-On Settings.
  6. Single Sign-On Settings page
     Click on "Edit" on top. Enable (Check tick) for SAML Enabled and save. Then click on "New". Give following settings on the following page.

    Single Sign-On Settings to use
    The settings for the super tenant at identity server. If you use another tenant please see below for the settings.
    • Name : SSO
    • API Name : SSO
    • Issuer : localhost
    • Identity Provider Login URL :  https://localhost:9443/samlsso
    • Identity Provider Logout URL : https://localhost:9443/samlsso
    • SAML Identity Type : Assertion contains User's salesforce.com username
    • SAML Identity Location : Identity is in the NameIdentifier element of the Subject statement
    • Entity Id : https://saml.salesforce.com
    • Identity Provider Certificate : To get this first open a terminal and cd to location at {WSO2 Identity Server Home}/repository/resources/security/. 
              There you will see the keystore for supertenant as wso2carbon. Use following command at terminal. 

              keytool -export -alias wso2carbon -file wso2.cert -keystore wso2carbon.jks -storepass wso2carbon

    A file named wso2.cert will be created at the same directory. Upload that file by clicking on "Choose File" in above window.
    The above settings should work good if you are going to work with the super tenant at the Identity Server side. If you use another tenant then you will have to do following changes. Others are just as same as above.

    Lets consider the tenant as "test.com". 
    • Entity Id : https://saml.salesforce.com@test.com
    • Identity Provider Certificate : To get this login to the identity server management console with tenant user created at tenant test.com. Go to the keystore. In the left pane Manage > Key Stores > List.
    Tenant Certificate
    Click on Public Key as shown above. Download and save the ".cert" file. Now upload that file by clicking on "Choose File" in above window at salesforce.
    After all these click save to save SAML SSO settings.




  7. After saving settings you will be redirected to following page. Click on "Download Metadata", to download there metadata. Keep this file as we need it later.
Saved Settings
Settings at the salesforce side are now done. Lets look at the settings to be done at Identity server.

Settings for the Identity Server

You can skip the following step only if you are not going to use "Enable Signature Validation in Authentication Requests and Logout Requests" or/and "Enable Assertion Encryption" options for the service provider.

If you have started the Identity Server, Shut it down. Open the metadata file downloaded in the final step above, in a text editor.

Metadata File
Go to the samltool X.509 formatter and copy the whole text within <ds:X509Certificate> tag. (Highlighted above.) Paste that text in the "X.509 cert" box and click "Format X.509 Certificate" button. Formatted text will appear in the next box named as "X.509 cert with header". Copy that whole text to a new text file and save it as "salesforce.cert". 

If you are going to use the supertenant,

then you can simply copy this "salesforce.cert" file in to {WSO2 Identity Server Home}/repository/resources/security/  folder. Then like before at the terminal go to the {WSO2 Identity Server Home}/repository/resources/security/ directory and run below command. 

keytool -import -file salesforce.cert -alias salesforce -keystore wso2carbon.jks -storepass wso2carbon

If you are using another tenant,

start the server and login with the respective tenant admin user. Go to the Manage > Key Stores > List as before. Click on "Import Cert". 


Import salesforce certificate
Click "Browse" and select "salesforce.cert". Click "Import". You will see the certificate listed under available certificates.

Available Certificates in keystore list
Following steps are mandatory to set the Identity Server.

  1. In management console go to Home > Service Provider > Add. Give a name and click "Register".
  2. Register Service Provider

  3. On the next window expand Inbound Authentication Configuration > SAML2 Web SSO Configuration > Configure
  4. Configure SAML2 Web SSO Confgiuration

  5. Next give the following values to respective field. To get to know about SAML 2 Web SSO settings options in deep refer this awesome blog.
Service Provider settings
            Issuer : https://saml.salesforce.com
            Assertion Consumer URL : This is the "Salesforce Login URL" in the SAML Sign On Settings window shown in the 5th step in Salesforce Settings.
            Certificate Alias : If you have gone the additional step above, "salesforce.cert" should be listed in the dropdown. You will have to select it if you are going to use "Enable Signature Validation in Authentication Requests and Logout Requests" or/and "Enable Assertion Encryption".

After all you can click Register to register the service provider. So the settings at two sides are done now. 

Let's create users at both sides.

Create Users at Salesforce

Log in to salesforce developer console.

To create a user go to Manage Users >  Users > New User. In the next window you will be asked for general information. User name must be in the format of an email address. (It doesn't have to be a email address. Just the format matters.) That is a limitation in salesforce.

Create Users at Identity Server side

When login your username should be identical with the user name you created at salesforce.
If you are using the supertenant users, you should enable <EnableEmailUserName> attribute properly in the identity server. Please find how to enable this feature in IS 5.1.0 from here. 

If you are unhappy to do that, we will find another hazlefree, easy way to do this with features provided in IS 5.1.0. For this you don't need to do above configuration. 

Go to IS management console. Home > Identity > Service Providers > List.  Select Edit of the salesorce identity provider to edit. Expand the Claim Configuration tab. Under the Subject Claim URI select http://wso2.org/claims/emailaddress. Now the email address of the user will be used as the subject. Don't forget to Update the service provider.

Claim Configuration
Since you have set the SAML Identity Location as Identity is in the NameIdentifier element of the Subject statement at SAML SSO Settings at salesforce, this will work perfect. So please assure that you have set it.

Now go to Home > Identity > Users and Roles > List and select users to get the users. Select the User Profile infront of the user you are going to use to login to salesforce. Give the username of the user you have created at salesforce side as the email address and save.

Ok we have done all the settings needed. Shall we test it.  Start the Identity Server if it is not already running. 
Open a new Private Browser Window. Go to the domain you have created by pasting it at the address bar. You will be redirected to the Identity Server SSO Login page.

SAML SSO Login Page at IS 
Give the user name and password you have used to login to Identity Server account where you have created the salesforce service provider. You will be successfully redirected to the salesforce dashboard.

Logged in to Sales Force Dashboard


Friday, December 4, 2015

Enable Tenant Dropdown in Single Sign On (SSO) loginpages - WSO2 Identity Server (5.1.0)

When you have multiple tenants in the same Identity Server instance, it is hard to remember which domain you should use with username, to login. When you use Single Sign On to login you will be redirected to the SSO login page. Since SP1 of WSO2 Identity Server 5.0.0 new feature was introduced to help users to select the tenant domain easily from a dropdown in the SSO login page. This feature is not default. In this post you will be able to enable this feature in IS - 5.1.0. Method is almost same in IS - 5.0.0 SP1. For demonstration we will use the IS dasboard at https://localhost:9443/dasboard. Go to this link, you will be redirected to SSO login page.


Here you can enter the username as username+@+tenantdoamin, and login.

We are going to load the tenants into a dropdown and give the ability of select the domain from the dropdown. After this you will not need to enter the tenantdomain. Just the username will be enough.

Procedure :
  1. Open the file at path {IS_Product_Home}/repository/conf/identity/EndpointConfig.properties. Set tenantListEnabled=true.

  2. Open the file at path {IS_Product_Home}/repository/conf/identity/application-authentication.xml.  Add following before </ApplicationAuthentication> element. 

  3. <TenantDomainDropDownEnabled>true</TenantDomainDropDownEnabled>
       <TenantDataListenerURLs>
            <TenantDataListenerURL>/authenticationendpoint/tenantlistrefresher.do</TenantDataListenerURL>
       </TenantDataListenerURLs>


  4. Open the file at path {IS_Product_Home}/repository/conf/tomcat/catalina-server.xml. Set clientAuth = "want", in the Connector for port : 9443 (what ever the port used by identity server management console)
If you are using IS 5.0.0 you will have to add following to the file at {IS_Product_Home}/repository/conf/security/authenticators.xml.

<Authenticator name="MutualSSLAuthenticator" disabled="false">
  <Priority>5</Priority>
  <Config>
      <Parameter name="UsernameHeader">UserName</Parameter>
      <Parameter name="WhiteListEnabled">false</Parameter>
      <Parameter name="WhiteList"/>
  </Config>
</Authenticator>

This should be set default in IS 5.1.0. However better to check this also. 

After setting all these start the IS server and go to the dashboard at https://localhost:9443/dasboard.
You will redirected to SSO loginpage with tenant dropdown. 


Select the tenant domain from the dropdown. Now you can login just by typing the username (don't have to append domain name) and password.

Wednesday, July 15, 2015

OAuth 2.0

Please visit the OAuth 2.0 page for the explanation. This page updates with the latest information. A separate page was created to provide the most updated information to you.

The new comers may be so reluctant to go through a lot of text to know what is OAuth 2.0. This post is for you, my dear folks. Enjoy it and give your kind feed backs to improve the presentation. Find the explanation, video and a simple demonstration of OAuth 2.0.

You don't need anything else to start working with OAuth 2.0. Just forget everything else and read. You will learn more when you started working. Enjoy it. Cheers!!!


Thursday, June 11, 2015

Performance of switch and if-else ladder

What is the fastest way to implement conditional clauses in JAVA?

Answer : SWITCH  :) But in an even contest.

Almost all the times it is much more efficient to use SWITCH instead of IF-ELSE.
But the contest is important. We are talking about an incident where you use only one variable to check for equivalence with one value.(As shown in the following example)

There is a difference in the view of the INTENT. That is switch can only be used for one variable and only for equivalence. But if-else is different. You can use more than one variable and compare in different ways with different conditions. So it is not fair to compare the performance of a complex if-else control flow and a switch. What we are talking in this short article is the FUNCTIONAL difference in the low level between these two control flow structures.

Yet in an even contest switch is considered to be more efficient. Sure, you may have heard this somewhere, but you may not know why? Well, that may be the only reason you are here.

Lets' dig deep a little.

Though we code in English, the machine understands bits. So the compiler compile and change our English code into machine code via assembly. It is how the 'if-else' ladder and 'switch' is organized at this point, that make switch more efficient. 

There are few defferent opcodes for if-else implementation. Every one compares two values and if succeeds do a jump (I.E branching) to the offset given as an operand in the comparison opcode.  The success of comparison is decided by the opcodes.

Lets take an even example for both scenarios.


if (counter == 5){// do stuff}
else if (counter ==10){//do stuff}
else if(counter ==15){//do stuff}
else{//default stuff}
switch(counter){
case 5 :
{// do stuff}
    break;
case 10 :
{//do stuff}
    break;
case 15 :
{//do stuff}
    break;
defaut:
    break;
}

You can see the difference of the coding structure. Though the simplest control (in the code level) flow structure is if-else, in the byte level the simplest is switch.

A switch generates a hash-table with key,value pair (case value and branch offset pairs)or a binary search tree. In the case of hash-table time to find out the branch offset is always O(1). In the case of binary search tree the time complexity will be log(n). The difference is between table-switch and lookup-switch respectively.

Here n is the number of cases in the ladder.

Wednesday, January 8, 2014

Configuring an existing MVC project correctly.

Today I had a little problem when I tried to add a view to an existing controller. The project was built on TFS by some other. When I started working on that it didn't workout in the usual manner. I rightclicked on the  controllermethod hoping to add a view. But it was not there. :(




It is very easy to fix this. :) I follow the solution first theory. Guys, be happy. We'll discuss later. Just follow these steps and you are done. If you want to UNDERSTAND read further. :)

  1. Make an MVC4 Project in Visual Studio.Open Visual Studiowhat ever the version you have. New Project->Web->ASP.NET MVC4 WebApplication
 Then on the next popup just click any template. I selected Empty template.
Now you have created a new MVC project. Hell!!!! we don't need this. Just close it. :o

 2.  Open your project folder. ASP.NET or MVC project which doesn't work as usual. There is the .csproj file. Right click on it and open it with a text editor. I use notepad++.




  3.  There you can see an XML type file. Find the tag with the XML heading <ProjectTypeGuids>.


 That is what you need. 

<ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>

In order to fix the problem we need to edit this tag. 

4. Go to that HELL project folder we created. Do the same in the step 2 and open the .csproj file in the text editor. Copy the respective part as follows.


 There maybe ONE or MANY keys in curly brackets as above. Doesn't matter. You need the first one only. Just copy and paste it in the place shown in step 3. That is to the problomatic .csproj file. Don't forget the semicolon at the end of curly brackets. Also you should copy it write infront of the list. Other words just after the <ProjectTypeGuids>.

Also when copying, you may be restricted to write this file. Then make sure you have deselected Read-Only option in properties. (Write click on the .csproj, <the image in step2>  and click properties. Then deselect the Read-Only option at bottom.)

So the edited .csproj will look like follow. (The same in step 3 after editing should looks like follow finally.)


Now save it man. Hola!!!! You are done. See, now I have the AddView, Go To view same as we do in a usual MVC project.




Let's dig in shortly what we have done.