Tuesday, 1 January 2013

Using Multi authentication in WebPasswordSafe

WebPasswordSafe ( is a Web based secure password store, and it supports multiple users with delegated access controls. The installation guide is available at

I deployed it and initially faced some issues when I tried to implement LDAP authentication using Active Directory. I would like to mention one point here, I found that in many applications which use LDAP authentication, automatically create a local user in the application whenever the user tries to login for the first time using LDAP login. But here I had to create a local user first with the same username as his/her LDAP login, then the user can use his/her LDAP credentials to login to the application.

WebPasswordSafe has few different authentication modes to authenticate a user. For my deployment I found Multi authentication most suitable, which allows using multiple Authenticator implementations for different sets of users. e.g. for admin user I can use local authentication and for other users I can use LDAP authentication.

So my webpasswordsafe-service.xml file that looks like (for using multi authentication):



<?xml version="1.0" encoding="UTF-8"?>
    Copyright 2008-2012 Josh Drummond
    This file is part of WebPasswordSafe.
    WebPasswordSafe is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.
    WebPasswordSafe is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    GNU General Public License for more details.
    You should have received a copy of the GNU General Public License
    along with WebPasswordSafe; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
<beans xmlns=""

    <!-- core services -->
    <context:component-scan base-package="net.webpasswordsafe.server.service" />

    <!-- pluggable services -->
    <bean id="passwordGenerator"
        class="net.webpasswordsafe.server.plugin.generator.SimpleRandomPasswordGenerator" >
        <property name="passwordLength" value="14" />
        <property name="allowLowercase" value="true" />
        <property name="allowUppercase" value="true" />
        <property name="allowNumeric" value="true" />
        <property name="specialChars" value="" />
        <property name="excludeChars" value="O0l1" />


    <bean id="authenticator"
        <property name="authenticator" ref="userLockoutAuthenticator" />
        <property name="failedLoginThreshold" value="10" />
        <property name="lockoutLength" value="1440" />
        <property name="whitelist">

    <bean id="userLockoutAuthenticator"
        <property name="authenticator" ref="multiAuthenticator" />
        <property name="failedLoginThreshold" value="5" />
        <property name="whitelist">

   <bean id="multiAuthenticator"
        <property name="authenticators">
                    <entry key="users">
                    <entry key="authenticator" value-ref="localAuthenticator"></entry>
                    <entry key="anyUser" value="true" />
                    <entry key="authenticator" value-ref="ldapAuthenticator"></entry>


   <bean id="authnContextSource" class="">
        <property name="url" value="ldap://" />
        <property name="userDn" value="CN=pranab,OU=Staff,DC=mkcl,DC=local" />
        <property name="password" value="12345678" />
    <bean id="authnLdapTemplate" class="org.springframework.ldap.core.LdapTemplate">
        <constructor-arg ref="authnContextSource" />
    <bean id="ldapAuthenticator" class="net.webpasswordsafe.server.plugin.authentication.LdapAuthenticator">
        <property name="ldapTemplate" ref="authnLdapTemplate" />
        <property name="filter" value="(&amp;(objectclass=person)(sAMAccountName=$1))" />
        <property name="base" value="OU=Staff,DC=mkcl,DC=local" />


   <bean id="localAuthenticator"

    <bean id="roleRetriever"
        <property name="adminUsers">

    <bean id="authorizer"
    <bean id="auditLoggerLog4j"
        <property name="delimiter" value=" || " />
    <bean id="auditLoggerDatabase"
        class="net.webpasswordsafe.server.plugin.audit.DatabaseAuditLogger" />
    <bean id="auditLogger"
        <property name="auditLoggers">
                <ref bean="auditLoggerLog4j" />
                <ref bean="auditLoggerDatabase" />
    <!--  Encryption related settings, these should not be changed after initial deployment otherwise
          data may be corrupted or unreadable -->
    <!-- ## Uncomment for Jasypt Encryption -->
    <bean id="digester" class="net.webpasswordsafe.server.plugin.encryption.JasyptDigester">
        <property name="passwordEncryptor" ref="passwordEncryptor" />
    <bean id="passwordEncryptor" class="org.jasypt.util.password.StrongPasswordEncryptor" />
    <bean id="encryptor" class="net.webpasswordsafe.server.plugin.encryption.JasyptEncryptor">
        <property name="stringEncryptor" ref="strongEncryptor" />
    <bean id="bcProvider" class="org.bouncycastle.jce.provider.BouncyCastleProvider" />
    <bean id="strongEncryptor" class="org.jasypt.encryption.pbe.StandardPBEStringEncryptor">
        <property name="algorithm" value="${encryptor.jasypt.algorithm}" />
        <property name="provider" ref="bcProvider" />
        <property name="password" value="${encryptor.jasypt.password}" />
        <property name="keyObtentionIterations" value="${encryptor.jasypt.keyObtentionIterations}" />




After using the application, I found that the admin user can see passwords of any user, even though permissions for those passwords were not given to the admin user. After some search I found this issue:

So again building the application by commenting the  BYPASS_PASSWORD_PERMISSIONS line in file worked for me. Now the admin user was not able to see the passwords (which were not shared with the admin user).