Wednesday, November 21, 2012

Identity management feature with WSO2 Identity Server


Identity management feature is a separate feature that is shipped as carbon feature that can be installed with WSO2 Identity server.  This is one of powerful feature that shows the extensibility of  WSO2 Carbon platform.  i.e.  This feature is an implementation of a listener interface in carbon user kernel. These listener implementations would be executed before of after a user kernel action is done such as adding user,  authentication and so on.    

Before going in to more implementation details,  In this blog post, let see what is supported by this feature by default. But always you can extend these as you wish.

Some of the features that is included...

1. User account verification methods
2. Password recovery methods
3. User account recovery methods.
4. Account locking / unlocking

Let see how we can install Identity management feature with WSO2 Identity Server 4.0.0

Lets Start from a fresh pack of WSO2 Identity Server 4.0.0 release which can be found at here

Step1 : Start server by running wso2server script file and login to management console 

Step2 : Go to feature manager UI and configure P2 repository which is available online


Step3 : Search for identity management feature 



Step4 : Install it by going through required steps. 



Step5 : Restart the server.



However due to following error, P2 installation would not work out of the box which would probably be fixed in next release.


Therefore you need to go through following additional step to get this work. 

1. Do proper attribute mapping with your user store 
2. Delete current database and create new one and start server with -Dsetup option (Basically you need to point to a new registry and user mgt database)
3. Uninstall SCIM feature from WSO2 Identity server. 

After this installation,  you would see new UI links with WSO2 Identity Server.  But most important thing is the APIs. There are two web service API, that has been deployed with identity management feature. These two API can be used by external application to implement identify management use cases.





Also there are some new configurations that you need to know in following configuration files

user-mgt.xml file

     Email and Captcha are used for account and password recovery processes. Therefore actual applications (may be application that uses WSO2 Identity Server API) can handle email sending and capatcha management as they like. Or else it can be delegated to WSO2 Identity server using following properties   
   
<Property name="emailSendingInternallyManaged">true</Property>
<Property name="captchaVerificationInternallyManaged">true</Property>

     After maximum number of failed login attempts, user account must be locked.  No of attempts can be configured. 

<Property name="maxFailedLoginAttempt">3</Property>

    When using temporary or one time password to create a user account, password can be configured as follows

<Property name="defaultPassword">123456</Property>


claim-config.xml 

There are new user attribute values that have been introduced with this feature. We need to properly configure those

email-admin-config.xml

If email is sent by WSO2 Identity Server, we need to configure the contain of it.  By using this file, we can configure it for different use cases. 

axis2.xml 

  If email is sent by WSO2 Identity Server, you need to configure axis2 email sender configurations 


        wso2is@gmail.com 
        wso2is 
        222222
        smtp.gmail.com

        587
        true
        true
     

Monday, November 12, 2012

Multiple user store manager feature with WSO2 Identity Server 4.0.0


This is powerful feature which is shipped with WSO2 Identity Server 4.0.0 release. With that feature, you are able to configure more than one user store with WSO2 Identity Server. User stores can be LDAP, JDBC or AD or combination of different user stores. Also it can be configured both read/write and read only modes.

I am going to use this feature to configure  LDAP with multiple OU (Organization Units) Where each OU is treated as different user store. There are some scenario where we want to treat OU as a separate user store by WSO2 Identity Server. As an example,  we want to connect different OUs, to WSO2 Identity Server with read-write mode and user must be created in a defined OU. 

First let assume our exiting LDAP structure as following....  where we have  three OU under the "pathberiya.com" domain (i.e dc=pathberiya, dc=com).  Each OU contains users and these users are assign to roles, i.e under the "pathberiya.com" domain.  Also there are users who are under the "pathberiya.com" domain. 





Step1.  Identify different OUs that must be connected with WSO2 Identity Server.  in above sample,  it would be 

ou=users,dc=pathberiya,dc=com,ou=system
ou=users,ou=it,dc=pathberiya,dc=com,ou=system
ou=users,ou=sales,dc=pathberiya,dc=com,ou=system
ou=users,ou=marketing,dc=pathberiya,dc=com,ou=system


Step2.  Creating user store configurations for each OU.  As each OU is treated as a user store,  So we need to create separate user store manager configurations and configure them in the user-mgt.xml file which can be found at <IS_HOME>/repository/conf directory.

(i) WSO2 Identity server identify each user store using a domain name. lets assign domain names for each OU. (any name what you prefer)

dc=pathberiya,dc=com,ou=system        ========== >    pathberiya.com
ou=users,ou=it,dc=pathberiya,dc=com,ou=system              ======= >    it.com
ou=users,ou=sales,dc=pathberiya,dc=com,ou=system         ======= >   sales.com
ou=users,ou=marketing,dc=pathberiya,dc=com,ou=system  ======= >    marketing.com 

Please note in  "pathberiya.com" domain,  all users in the four OUs can be seen.

(ii) We need to identify one user store as the primary user store.  Primary user store must be configured as the first user store configuration in the user-mgt.xml file. Let see what are the functions of primary user store.
  • If domain name is not defined for user,  then user is 1st authenticated with primary user store, If it is not successful,  then user is authenticated with other user store according to the order that has been configured in user-mgt.xml file.
  • User Management UI of the WSO2 Identity server is loaded from this user store. Basically User Management UI does not show users of other user store.
So as all users are defined for  "pathberiya.com" domain,  we set this domain as primary user store.

(iii) Then lets identify role search based for WSO2 Identity Server's roles.

ou=roles,dc=pathberiya,dc=com,ou=system

(iv) Then we need to identify the admin user and role for WSO2 Identity Server from above user stores (OUs)

let select  user called "adminUser" in primary user store as the admin user for WSO2 Identity Server. And  "admin" role in  ou=roles,dc=pathberiya,dc=com,ou=system as admin role  for WSO2 Identity Server.

lets see our final configuration of the user-mgt.xml file.  Please fine here 

Basically you can create one user store configuration as following and you can create others user store configurations for each OUs  easily by changing  the "UserSearchBase" , "UserDNPattern" and "DomainName" attributes. 
 
            ldap://localhost:10389
            uid=admin,ou=system
            secret
            (objectClass=person)
     inetOrgPerson
            ou=users,ou=it,dc=pathberiya,dc=com,ou=system
            (&(objectClass=person)(uid=?))
            uid
     [a-zA-Z0-9._-]{3,30}$
            ^[\\S]{3,30}$
     ^[\\S]{3,30}$
            [a-zA-Z0-9._-]{3,30}$
            ^[\\S]{5,30}$
     true
     true
     false
            ou=roles,dc=pathberiya,dc=com,ou=system
            (objectClass=groupOfNames)
            groupOfNames
            (&(objectClass=groupOfNames)(cn=?))
            cn
            member
            true
     true
            uid={0},ou=users,ou=it,dc=pathberiya,dc=com,ou=system
            it.com
        


Step3. Start WSO2 Identity Server by running wso2server script file from  <IS_HOME>/bin directory


Step4. Try  authentication and user management function with sample client. (or Soapui ).  Here is the sample code to run user management functions.

Here when authenticating the users,  if the user  (say user called "user1") is in the it.com domain (IT OU), then you need to pass the user name as   it.com/user1

When creating user in sales domain (Sales OU), you need to create the user by providing user name as "sales.com/newUser1"

Friday, November 9, 2012

Disabling WS-Security for IN or OUT messages in Axis2


This is another blog post on WS-Security with Apache Rampart.  Usually, when we are securing a web service with WS-Security, both web service request and response messages are secured. But there are scenarios where you want to configured WS-Security only for web service request or either service response messages.  Say, you may providing some secret data to web server, but web server responses just saying "yes" or "no".  Here you do not want to worry on securing response message.  So like that,  there are several use cases with this. 

Lets see how we can configure this with Apache Rampart; security module of Axis2 

There are two approaches for this. 

Approach 1 : Apache Rampart is an axis2 module where it encapsulates several axis2 handlers.  Configuration file called "module.xml" can be used for configuring this module. If we want to remove security processing for response messages,  we can just remove the defined axis2 handlers from the OutFlow selection. 

But there is a drawback with this.  If we remove axis2 handlers from the OutFlow selection,  Then this would effect for all the services that are deployed in the axis2 engine. Therefore,  there are must be a way to configure this in service level. 


Approach 2 :  As suggest in here,  We can write a new simple module (say "NoSecurity" module) and plug it with axis2 handler chain where this module can ask to skip the rampart module (handlers).  Therefore we can engage "NoSecurity" module only for desired services 


However it is not easy to write a module to skip rampart. Therefore i have used the concept of IN and OUT policies in Rampart. Here we are configuring OUT policy that has no security assertion  to skip the security processing. 

"NoSecurity" Project contains  handler called "NoSecurityHandler" that inject the IN or OUT policy to rampart.  This handler must be placed in the "NoSecurity" phase of axis2 message flows.  Handler has been enclosed with the "NoSecyrityModule" module.

Let see how we can configure this module in a practical use case.  

User case 1

WSO2AS as our web service engine and let try to apply this module for echo service that has been hosted there. 

Step1.  Please do desired changes in to the module and build it with maven.  You would find the .mar module in target directory

Step2. Copy .mar module in to   <CARBON_HOME>/repository/deployment/server/axis2modules  directory. 

Step3. Configure new  "NoSecurity" phase in axis2.xml file which can be found at <CARBON_HOME>/repository/conf/axis2 directory.

Here you can select the desired flow.   i.e.  InFlow, OutFlow InFaultFlow and OutFaultFlow.  Here i am configuring it OutFlow  before the "Security" Phase. 

Step4. Restart the server

Step5  Login to management console of Carbon Server and Go to Service dashboard page of echo service 


Step6. Go to module configuration and select your "NoSecurity" module to engage.



Step7. Now you are done, you can engage and disengage this module for each services using Carbon management console.




User case 2

WSO2 ESB as proxy service engine for your message meditation.  Here we are going to engage this module to disable the security check of incoming message from BE service.  Therefore it is little bit different on writing the module.  Because WSO2 ESB deals with two InFlows  i.e   Messages coming to proxy service and Response messages from BE service.




If we want to only enable this module for messages coming from BE services. We can have a simple check  of a property called "synapse.send"
 if("true".equals(messageContext.getProperty("synapse.send"))){ 

 }
Please find the module project for this for here.   Configuration steps would be same as in WSO2AS, only thing is,  we need to select the correct axis2 phase.

Monday, November 5, 2012

How to invoke secured backend service using WSO2 ESB

Please visit new my blog for this blog post from here





WSO2 ESB can be used for implementing various security patterns in your SOA. It supports message level security with WS-Security specification. In this blog post, we are going to use WSO2 ESB to invoke a secured BE service. 

Client ------------------->  WSO2 ESB -------------------> BE service. 

Lets assume BE service is secured with WS-Security policy.  

Policy contains both signature and encryption  and client needs to provide X509 certificate for authentication. It mean WSO2 ESB proxy service must be authenticated to the BE service.   Therefore security policy provides the authentication Integrity and Confidentiality. 

Here is WSDL of the BE service. It is just a simple echo service. 

Lets go through step by step

Step1 : We need to create matching policy for WSO2 ESB side to invoke the BE service. We can just copy the policy from WSDL for this. It would be some thing like this

Step2 : To do the encryption and signing, we need to define the certificates that contains private key and public key for this.  This is done through a configuration. 

WSO2 ESB uses Apache rampart as the WS-Security implementation. Rampart has, it own way to define the key store and key data using configuration called "rampart configuration". We can add this rampart configuration, in to the Security Policy as an assertion.  Please find more details about rampart configurations from here

Lets add rampart configuration. 

To sign and encryption,  we need to specify following....    

1. Signature and Encryption  crypto. as we are using keystores,   i.e  keystore details.   Such as keystore file, password, type and so on. 

We can define them as follows ...
  

                        
                            JKS
                            /home/asela/Security/resources/keys/client.jks
                            apache
                        
                    
                    
                        
                            JKS
                            /home/asela/Security/resources/keys/client.jks
                            apache
                        
                    

2  Private key (certificate) that is going to sign the message 

This the certificate alias name of private key of the client.jks file
client
3. Public key (certificate) that is going to encrypt the message

This is the certificate alias name of the public certificate of the BE service. That is also contains in my client.jks file.
service
4. Private key password 

We can not define private key password in rampart configuration,  we need to provide it through password class back implementation. Therefore here i am defining the class name of the password call back implementation 
org.wso2.samples.pwcb.PWCBHandler
Now we are done with policy,  it would be as this


Step3 : Lets create a password call back class to inject private key password.  You can get help from this blog post. 

Step4 : Upload our policy to the WSO2 ESB. Here we are uploading created policy file as a resource in the WSO2 ESB's registry. 

1.  Login to WSO2 ESB management console and Go to  "Registry Browser" 



2. Add new registry collection  (folder) in preferred location. I have selected governance collection for this  



3. Upload policy from file system as a resource. 



Step5 : Create  ESB end point for BE service with security

1. Go to  Endpoint configuration UI in Management console 



2. Create new address end point with your BE service configuration and then select advance options. 



3. Select WS-Security option under the QoS in advance options



4. Select Governance registry collection to local the uploaded policy 



5. Finish the endpoint creation 


Step6 :  Create sample proxy service with our secured endpoint.

There are different ways to create proxy service according to your preferences. Here i am creating simple pass through proxy 

1. Create proxy service by defining the endpoint created above



2. You can see synapse configuration as following in proxy and endpoint configurations  



Now we are done...!!!  You can invoke the proxy service with non-secured client. 

Previous 

Secured Client ------------------------------------------------>  Secured BE service 

Now with WSO2ESB

Non Secured Client 
(Endpoint is changed to proxy enpoint) ---------> WSO2ESB  -------------> Secured BE service 





Sunday, August 12, 2012

Secure plain text passwords in WSO2 Carbon configuration files


Please visit new my blog for this blog post from here


If you go through the conf directory of WSO2 products, there are some configuration file, that contains secret informations such as passwords...This blog post describes how we can secure the plain text passwords in these configuration files. This [1] document gives you clear understanding about secure vault implementation. But here i am going step by step to configure it. Please note this configurations only valid for carbon 3.2.X products.  But with 4.0.X release, steps are same..  but there are new configurations files....  as an example,  we have "master-datasources.xml" file which can be found in "conf/datasources".  In this file, we are configuring all data source related configurations...  Therefore database configuring passwords would be in this file.   



First, let see what are the secret information that can be secured. Following are the alias names and secrets of carbon configuration files.  

1. in user-mgt.xml  

UserManager.AdminUser.Password -> Admin User password in user-mgt.xml
UserManager.Configuration.Property.password -> User Manager database connection password in user-mgt.xml  
(Only in 3.2.X)
UserStoreManager.Property.ConnectionPassword -> User store connection password in user-mgt .xml 

2. in registry.xml (Only in 3.2.X )

wso2registry.[Registry Name].password -> Registry database connection password in registry.xml 

3. in carbon.xml

Carbon.Security.KeyStore.Password- > Keystore password of Carbon server in carbon.xml
Carbon.Security.KeyStore.KeyPassword -> Private key password of Carbon server in carbon.xml
Carbon.Security.TrustStore.Password -> Trust store password of Carbon server in carbon.xml 

4. in mgt-transport.xml   (Only in 3.2.X )

transports.https.keystorePass -> SSL key and keystore password in mgt-transport.xml 

5.  master-datasources.xml  (With Carbon 4.0.X Only)

Datasources.[Data source name].Configuration.Password  ->  Database connection password of defined data source.  There can be more than one datasource configurations in this file.

Also by using secure vault you can secure the passwords in axis2.xml file, i.e.

Axis2.Https.Listener.TrustStore.Password -> NIO Listener SSL trust store password in axis2.xml
Axis2.Https.Listener.KeyStore.Password -> NIO Listener SSL keystore store password in axis2.xml
Axis2.Https.Listener.KeyStore.KeyPassword -> NIO Listener SSL key password in axis2.xml
Axis2.Https.Sender.TrustStore.Password -> NIO Sender SSL trust store password in axis2.xml
Axis2.Https.Sender.KeyStore.Password -> NIO Sender SSL key store password in axis2.xml
Axis2.Https.Sender.KeyStore.KeyPassword -> NIO Sender SSL key password in axis2.xml
Axis2.Mailto.Parameter.Password -> Email sender password in axis2.xml 


Step 1.   Locate cipher-text.properties which can be found at <CARBON_HOME>/repository/conf directory in your WSO2 product.  This file contains the alias names and the corresponding plain text password in square brackets. 

If you can not find this file in your product, Please download it from this svn location [2]  and copy to above location. 

Step 2.  Configure cipher-text.properties file with your passwords. 

As an example, I want to secure keystore passwords of carbon.xml file (You should secured them as encryption is done with it) ,  both database and LDAP connection password of user-mgt.xml file.  My cipher-text.properties would be as follows,


Carbon.Security.KeyStore.Password=[mykeystorepass]

Carbon.Security.KeyStore.KeyPassword=[mykeystorepass]

Carbon.Security.TrustStore.Password=[mytruststorepass]
UserManager.Configuration.Property.password=[myuserdbpass]
UserStoreManager.Property.ConnectionPassword=[myldappass]

Step 3. Locate  "ciphertool" script which can be found at <CARBON_HOME>/bin directory. If you can not find this file in your product, Please download it from this svn location [3]  and copy to above location.

Step 4. Run "ciphertool" script with -Dconfigure option.  

as an example in UNIX,

>ciphertool.sh  -Dconfigure

This script does followings 
1. encrypt the passwords defined in cipher-text.properties file
2. remove plain text passwords in conf files.
3. configure  secret-conf.properties file

Step 5. Check above mentioned files, are properly configured. 

Step 6. Start server.     in startup, server would promote for  master password (i.e is key store password) you need to provide it. 


Personally, I do not like to provide master password each server startup,  although it is one of a secured way to provide it....  This is the default way of providing the master password according to this [4].  You can write your own implementation for this. Therefore i just write a simple implementation for this where i have hard coded my master password. Please find the my project from here [5]. 

Let see how we can configure new master password callback handler

1. Replace the default password handler class name (org.wso2.carbon.securevault.DefaultSecretCallbackHandler) from secret-conf.properties file and configure my own one (com.sample.password.callback.handler.HardCodedSecretCallbackHandler). 

2. Copy own implementations as a jar file in to <CARBON_HOME>/repository/components/lib directory 

3. If you have secured the passwords in mgt-transport.xml file, Please Copy your jar file to <CARBON_HOME>/lib/api directory.

4. Restart the server.


Links again :) 





  

Wednesday, August 8, 2012

Enable Mutual SSL for Proxy services in WSO2ESB - II

This is my second blog post about enabling mutual SSL for ESB  proxy services. In my previous blog post,  we enabled mutual SSL for all deployed proxy services. But in this blog post,  we are going  to enable it for only selected proxy services. Let assume we have proxy service call "TestProxy" and also there are many other proxy services that have been deployed in WSO2ESB.  We want to enable mutual SSL for "TestProxy" only. Let see how we can do it. Here we are using transport binding in WS-Security. 

I assume that you have gone through my previous blog post,  therefore i am not going to much details  in some configurations

Step 1 : Configure  "SSLVerifyClient" property to optional in NIO transport receiver and Restart the server. 

Step 2. Secure TestProxy using security scenario 1 (Username Token authentication) 

Step 3. Modify applied policy in to this policy using policy editor.  Here we have remove the user name token validation and forced the client certificated.

Step 4. Apply these patched jars to WSO2ESB 4.0.3 distribution. Copy and Replace in to <ESB_HOME>/repository/components/plugins.  Actually we have done small modification  to bring the client certificate in to rampart level and validate it at that level 
 
Step 5. Step you key stores and trust stores as described in my previous post

Step 6. Invoke the "TestProxy" using sample client which can be found at here

If you have not used  a key store or your certificate does not contain in the NIO transport receiver's trust store file; you would probably experience following error.
 
[2012-08-08 18:02:47,879] ERROR - AxisEngine Service requires SSL mutual authentication
org.apache.axis2.AxisFault: Service requires SSL mutual authentication
at org.apache.rampart.handler.RampartReceiver.setFaultCodeAndThrowAxisFault(RampartReceiver.java:180)
at org.apache.rampart.handler.RampartReceiver.invoke(RampartReceiver.java:99)
at org.apache.axis2.engine.Phase.invokeHandler(Phase.java:340)

 

Enable Mutual SSL for Proxy services in WSO2ESB - I

Please visit new my blog for this blog post from here




Lets see how we can enable mutual SSL (two-way SSL) for all the proxy services that are deployed in WSO2 ESB

Step 1 :  Enable mutual SSL for NIO transport receiver


WSO2 ESB uses NIO transport for sending and receiving messages.  You can find NIO transport  receiver and sender configuration  from axis2.xml file which can be found at <ESB_HOME>/repository/conf directory. Under the transport receiver,  there are key store and trust store configurations as follows.  

By default 
1. mutual authentication is not enabled
2. for keystore and trust store,  WSO2ESB is using the default wso2carbon.jks and client-truststore.jks file

Therefore you need to change those default parameters. Here i have changed only the "SSLVerifyClient" parameter to "require" to enable mutual authentication for all services that has been exposed via NIO

    <transportReceiver name="https" class="org.apache.synapse.



transport.nhttp.

HttpCoreNIOSSLListener">
        <parameter name="port" locked="false">8243</
parameter>
        <parameter name="non-blocking" locked="false">true</
parameter>
        <parameter name="keystore" locked="false">
            <KeyStore>
                <Location>repository/
resources/security/wso2carbon.


jks</Location>
                <Type>JKS</Type>
                <Password>wso2carbon</
Password>
                <KeyPassword>wso2carbon</
KeyPassword>
            </KeyStore>
        </parameter>
        <parameter name="truststore" locked="false">
            <TrustStore>
                <Location>repository/
resources/security/client-


truststore.jks</Location>
                <Type>JKS</Type>
                <Password>wso2carbon</
Password>
            </TrustStore>
        </parameter>
          <parameter name="SSLVerifyClient">
require</parameter>
    </transportReceiver>


After configuration is finished, Restart WSO2ESB server, if you have already started. Then just create a simple pass through proxy service call "TestProxy". 



Step 2 :  Writing Axis2 client to invoke  

You can find the client program for here. To run the client program you need to setup your key store and trust store properly.  Actually we can use same key store file as both key store (which contains private key) and trust store (which contains trusted certificates)

First we need to import the NIO transport receiver's certificate to client's trust store file

Please export NIO transport receiver's 
certificate from key store.  As a sample, you can use keytool command as follows.

> keytool -export -keystore wso2carbon.jks -alias localhost -file wso2.crt

Please import NIO certificate in to client trust store.

> keytool -import -keystore client.jks -alias wso2carbon -file wso2.crt

Now you have setup the SSL properly. If this is not properly done,  when you tries with sample client, you would receive following error in client side.
 


org.apache.axis2.AxisFault: Connection has been shutdown: javax.net.ssl.
SSLHandshakeException: sun.security.validator.


ValidatorException: PKIX path building failed: sun.security.provider.

certpath.
SunCertPathBuilderException: unable to find valid certification path to requested target
at org.apache.axis2.AxisFault.
makeFault(AxisFault.java:430)  

Then we need to import client's certificate in to the NIO transport receiver's trust store file. Please go through above keytool command for this also
Now you have setup the SSL properly.  If not, when you tries with sample client, you would receive following error in client side.

Exception in thread "main" org.apache.axis2.AxisFault: Connection has been shutdown: javax.net.ssl.SSLException: java.net.SocketException: Connection reset
at org.apache.axis2.AxisFault.
makeFault(AxisFault.java:430)
at org.apache.axis2.transport.
http.SOAPMessageFormatter.


writeTo(SOAPMessageFormatter.

java:78)

And in server side.

[2012-08-08 17:29:56,390] ERROR - ServerHandler I/O error: null cert chain
javax.net.ssl.
SSLHandshakeException: null cert chain
at com.sun.net.ssl.internal.ssl.
Handshaker.checkThrown(


Handshaker.java:1015)

Now you know how to secure  WSO2ESB  proxy  services using mutual SSL and invoke them.  In my next blog post let see,  how we can secure only the one or two WSO2ESB  proxy  services using mutual SSL(Not all)