/* * JOSSO: Java Open Single Sign-On * * Copyright 2004-2009, Atricore, Inc. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. * */ package org.josso.gateway.identity.service.store.ldap; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.josso.auth.BindableCredentialStore; import org.josso.auth.exceptions.AuthenticationFailureException; import org.josso.auth.exceptions.SSOAuthenticationException; import javax.naming.AuthenticationException; import javax.naming.ldap.InitialLdapContext; /** * An implementation of an Identity and Credential Store which obtains credential, user and * role information from an LDAP server using JNDI, based on the configuration properties. * <p/> * It allows to set whatever options your LDAP JNDI provider supports your Gateway * configuration file. * Examples of standard property names are: * <ul> * <li><code>initialContextFactory = "java.naming.factory.initial"</code> * <li><code>securityProtocol = "java.naming.security.protocol"</code> * <li><code>providerUrl = "java.naming.provider.url"</code> * <li><code>securityAuthentication = "java.naming.security.authentication"</code> * </ul> * <p/> * This store implementation is both an Identity Store and Credential Store. * Since in JOSSO the authentication of the user is left to the configured Authentication Scheme, * this store implementation cannot delegate user identity assertion by binding to the * LDAP server. For that reason it retrieves the required credentials from the directory * leaving the authentication procedure to the configured Authentication Scheme. * The store must be supplied with the configuratoin parameters so that it can retrieve user * identity information. * <p/> * <p/> * Additional component properties include: * <ul> * <li>securityPrincipal: the DN of the user to be used to bind to the LDAP Server * <li>securityCredential: the securityPrincipal password to be used for binding to the * LDAP Server. * <li>securityAuthentication: the security level to be used with the LDAP Server session. * Its value is one of the following strings: * "none", "simple", "strong". * If not set, "simple" will be used. * <li>usersCtxDN : the fixed distinguished name to the context to search for user accounts. * <li>principalUidAttributeID: the name of the attribute that contains the user login name. * This is used to locate the user. * <li>rolesCtxDN : The fixed distinguished name to the context to search for user roles. * <li>uidAttributeID: the name of the attribute that, in the object containing the user roles, * references role members. The attribute value should be the DN of the user associated with the * role. This is used to locate the user roles. * <li>roleAttributeID : The name of the attribute that contains the role name * <li>credentialQueryString : The query string to obtain user credentials. It should have the * following format : user_attribute_name=credential_attribute_name,... * For example : * uid=username,userPassword=password * <li>userPropertiesQueryString : The query string to obtain user properties. It should have * the following format : ldap_attribute_name=user_attribute_name,... * For example : * mail=mail,cn=description * </ul> * A sample LDAP Identity Store configuration : * <p/> * <pre> * <sso-identity-store> * <class>org.josso.gateway.identity.service.store.ldap.LDAPBindIdentityStore</class> * <initialContextFactory>com.sun.jndi.ldap.LdapCtxFactory</initialContextFactory> * <providerUrl>ldap://localhost</providerUrl> * <securityPrincipal>cn=Manager\,dc=my-domain\,dc=com</securityPrincipal> * <securityCredential>secret</securityCredential> * <securityAuthentication>simple</securityAuthentication> * <usersCtxDN>ou=People\,dc=my-domain\,dc=com</usersCtxDN> * <principalUidAttributeID>uid</principalUidAttributeID> * <rolesCtxDN>ou=Roles\,dc=my-domain\,dc=com</rolesCtxDN> * <uidAttributeID>uniquemember</uidAttributeID> * <roleAttributeID>cn</roleAttributeID> * <credentialQueryString>uid=username\,userPassword=password</credentialQueryString> * <userPropertiesQueryString>mail=mail\,cn=description</userPropertiesQueryString> * </sso-identity-store> * </pre> * <p/> * A sample LDAP Credential Store configuration : * <p/> * <pre> * <credential-store> * <class>org.josso.gateway.identity.service.store.ldap.LDAPBindIdentityStore</class> * <initialContextFactory>com.sun.jndi.ldap.LdapCtxFactory</initialContextFactory> * <providerUrl>ldap://localhost</providerUrl> * <securityPrincipal>cn=Manager\,dc=my-domain\,dc=com</securityPrincipal> * <securityCredential>secret</securityCredential> * <securityAuthentication>simple</securityAuthentication> * <usersCtxDN>ou=People\,dc=my-domain\,dc=com</usersCtxDN> * <principalUidAttributeID>uid</principalUidAttributeID> * <rolesCtxDN>ou=Roles\,dc=my-domain\,dc=com</rolesCtxDN> * <uidAttributeID>uniquemember</uidAttributeID> * <roleAttributeID>cn</roleAttributeID> * <credentialQueryString>uid=username\,userPassword=password</credentialQueryString> * <userPropertiesQueryString>mail=mail\,cn=description</userPropertiesQueryString> * </credential-store> * </pre> * * @org.apache.xbean.XBean element="ldap-bind-store" * * @author <a href="mailto:gbrigand@josso.org">Gianluca Brigandi</a> * @version CVS $Id: LDAPBindIdentityStore.java 543 2008-03-18 21:34:58Z sgonzalez $ */ public class LDAPBindIdentityStore extends LDAPIdentityStore implements BindableCredentialStore { private static final Log logger = LogFactory.getLog(LDAPBindIdentityStore.class); // ----------------------------------------------------- CredentialStore Methods /** * This store performs a bind to the configured LDAP server and closes the connection immediately. * If the connection fails, an exception is thrown, otherwise this method returns silentrly * * @return true if the bind is successful */ public boolean bind(String username, String password) throws SSOAuthenticationException { try { // first try to retrieve the user using an known user String dn = selectUserDN(username); if (dn == null) { // user not found throw new AuthenticationFailureException("No DN found for user : " + username, "AUTH_FAILED_NO_USER"); } else { logger.debug("user dn = " + dn); } try { // Try to bind to LDAP an check for authentication problems. InitialLdapContext ctx = this.createLdapInitialContext(dn, password); ctx.close(); } catch (AuthenticationException e) { if (logger.isDebugEnabled()) logger.debug("Authentication error : " + e.getMessage(), e); return false; } return true; } catch (Exception e) { if (e instanceof AuthenticationFailureException) { throw new AuthenticationFailureException("Cannot bind as user : " + username + " " + e.getMessage(), ((AuthenticationFailureException) e).getErrorType()); } else { throw new SSOAuthenticationException(e.getMessage(), e); } } } }