Saturday, August 6, 2016

Writing Custom Password Pattern Validator Policy Extensions in WSO2 Identity Server

WSO2 Identity Server is an enterprise class Identity and Access Management Solution. From my previous two blog posts [1] and [2],  I discussed how to enforce password pattern policies for user accounts and also demonstrated the default password pattern policy extensions. From this post I am showing you how to write your own password pattern policy extension for validating and enforcing security in passwords. Here I use WSO2 Identity Server 5.1.0 version which is the latest released version by the time of this writing.

A typical example for writing your own password pattern policy extension would be to avoid having dictionary words in passwords. This kind of a password pattern validation is not available in Identity Server out of the box, but you can write an extension to achieve this.

A password pattern policy extensions is a Java class that we write, build and deploy in Identity Server. The extension can accept parameters that can be defined in configuration file (identity-mgt.properties). Following are the properties that we have to define in <IS_HOME>/repository/conf/identity/identity-mgt.properties file for engaging an extension.

Password.policy.extensions.<sequence number>=<fully qualified class name>

Password.policy.extensions.<sequence number>.<parameter name>=<parameter value>

Every extension should have a sequence number. It is an integer starting from 1 and incrementing by 1. At run time, when the password validation happens, these extensions get executed according to the sequence number. If the extension needs to accept parameters, we can define the parameters one by one as given above.

Following is an extension that is by default coming in Identity Server. The sequence number is 1. It accepts two parameters namely “min.length” and “max.length”.

Password.policy.extensions.1=org.wso2.carbon.identity.mgt.policy.password.DefaultPasswordLengthPolicy
Password.policy.extensions.1.min.length=6
Password.policy.extensions.1.max.length=12

Now let’s get started with writing our extension.

We need to write a Java class that extends org.wso2.carbon.identity.mgt.policy.AbstractPasswordPolicyEnforcer class [3].  This abstract class is implementing the interface org.wso2.carbon.identity.mgt.policy.PolicyEnforcer  [4]. This interface has init method which receives the parameters defined in identity-mgt.properties file under the particular extension. Apart from that the interface contains the enforce method that gets hit when a password is going to be set for a user account.

For demonstration purpose, I am writing a password pattern policy to avoid password containing dictionary words. Basically I’m creating a list and hard code some words and when the password is going to be set, it will iterate through the list and check if the password does not contain any word in the dictionary. Referring this sample, you can write an extension that suits your requirement.

The source code of the sample project can be found in git repo [5]. It is a maven java project.

Once you build the project you get the com.wso2.password.policy-1.0.0.jar file. If you do not want to build the project but just want to try this out, the built jar file can be found in the target directory of [5]. You have to copy this jar file to IS_HOME/repository/components/dropins directory. (because this jar file is OSGI supported [6]).

Then we need to engage this extension with Identity Server. For that, we need to add following properties to identity-mgt.properties file.

Password.policy.extensions.1=com.wso2.password.policy.CustomPasswordPatternPolicy
Password.policy.extensions.1.errorResponse='Password pattern policy violated. Password should not contain dictionary words'

Here I have removed the by default shipped 3 extensions and put only this extension. Therefore I have given the sequence number of the extension as 1. In the properties, it has the fully qualified class name of the extension and then it accepts errorResponse parameter which I use to display an error message upon password pattern violation.

Next step is to enable the IdentityMgtEventListener so that these extensions are evaluated at run time. It has to be enabled in IS_HOME/repository/conf/identity/identity.xml file.

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


Now we have configured our new extension and we need to restart the server for the changes to be effective.

In this extension, as the dictionary words, I just defined “hello” and “world” words [7]. Therefore if the password of a user account contains any of these words, it would violate the policy and give the error message.

Testing the Password Pattern Policy Extension from Management Console

Now I login to Management Console of Identity Server and try to create a user.


As the password, I give a string that contains the word “hello”. Proving that the extension works as expected, I get the following error message which I defined as a parameter to the extension.


In the logs, we see that the password pattern policy is violated where the logs I added have got printed.


If I create a user account giving a password that does not contain the dictionary words (from the words list defined in code), then I can successfully set the password for the account. I see the following logs which says that the password complies with the policy. This log was added in the code for demonstration purpose.


Testing the Password Pattern Policy Extension from RemoteUserStoreManagerService API
These extensions are coming from backend. Therefore even if I create the user account by calling the user management API, it should work. For that I call the RemoteUserStoreManagerService [8] SOAP service in WSO2 Identity Server which provides methods for managing user accounts. In that, I call the addUser method where for the password I give a string that contains a dictionary word.
As the response I get the same error message and therefore the password pattern policy extension works as expected.

You can refer the above sample I discussed and write your own password pattern policy extension to satisfy your requirements.

References



Tharindu Edirisinghe
Platform Security Team
WSO2

No comments:

Post a Comment