https://issues.apache.org/jira/browse/AMQ-3323 - LDAPLoginModule more debuging and exception messages

git-svn-id: https://svn.apache.org/repos/asf/activemq/trunk@1103745 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Bosanac Dejan 2011-05-16 14:19:46 +00:00
parent b5579ac1ca
commit e1ce619872
3 changed files with 116 additions and 19 deletions

View File

@ -131,16 +131,10 @@ public class LDAPLoginModule implements LoginModule {
else else
password=""; password="";
try { // authenticate will throw LoginException
boolean result = authenticate(username, password); // in case of failed authentication
if (!result) { authenticate(username, password);
throw new FailedLoginException(); return true;
} else {
return true;
}
} catch (Exception e) {
throw (LoginException)new LoginException("LDAP Error").initCause(e);
}
} }
@Override @Override
@ -173,13 +167,23 @@ public class LDAPLoginModule implements LoginModule {
} }
} }
protected boolean authenticate(String username, String password) throws Exception { protected boolean authenticate(String username, String password) throws LoginException {
MessageFormat userSearchMatchingFormat; MessageFormat userSearchMatchingFormat;
boolean userSearchSubtreeBool; boolean userSearchSubtreeBool;
DirContext context = null; DirContext context = null;
context = open();
if (log.isDebugEnabled()) {
log.debug("Create the LDAP initial context.");
}
try {
context = open();
} catch (NamingException ne) {
FailedLoginException ex = new FailedLoginException("Error opening LDAP connection");
ex.initCause(ne);
throw ex;
}
if (!isLoginPropertySet(USER_SEARCH_MATCHING)) if (!isLoginPropertySet(USER_SEARCH_MATCHING))
return false; return false;
@ -208,10 +212,18 @@ public class LDAPLoginModule implements LoginModule {
list.toArray(attribs); list.toArray(attribs);
constraints.setReturningAttributes(attribs); constraints.setReturningAttributes(attribs);
if (log.isDebugEnabled()) {
log.debug("Get the user DN.");
log.debug("Looking for the user in LDAP with ");
log.debug(" base DN: " + getLDAPPropertyValue(USER_BASE));
log.debug(" filter: " + filter);
}
NamingEnumeration<SearchResult> results = context.search(getLDAPPropertyValue(USER_BASE), filter, constraints); NamingEnumeration<SearchResult> results = context.search(getLDAPPropertyValue(USER_BASE), filter, constraints);
if (results == null || !results.hasMore()) { if (results == null || !results.hasMore()) {
return false; log.warn("User " + username + " not found in LDAP.");
throw new FailedLoginException("User " + username + " not found in LDAP.");
} }
SearchResult result = results.next(); SearchResult result = results.next();
@ -229,7 +241,7 @@ public class LDAPLoginModule implements LoginModule {
Attributes attrs = result.getAttributes(); Attributes attrs = result.getAttributes();
if (attrs == null) { if (attrs == null) {
return false; throw new FailedLoginException("User found, but LDAP entry malformed: " + username);
} }
List<String> roles = null; List<String> roles = null;
if (isLoginPropertySet(USER_ROLE_NAME)) { if (isLoginPropertySet(USER_ROLE_NAME)) {
@ -240,19 +252,26 @@ public class LDAPLoginModule implements LoginModule {
if (bindUser(context, dn, password)) { if (bindUser(context, dn, password)) {
// if authenticated add more roles // if authenticated add more roles
roles = getRoles(context, dn, username, roles); roles = getRoles(context, dn, username, roles);
if (log.isDebugEnabled()) {
log.debug("Roles " + roles + " for user " + username);
}
for (int i = 0; i < roles.size(); i++) { for (int i = 0; i < roles.size(); i++) {
groups.add(new GroupPrincipal(roles.get(i))); groups.add(new GroupPrincipal(roles.get(i)));
} }
} else { } else {
return false; throw new FailedLoginException("Password does not match for user: " + username);
} }
} catch (CommunicationException e) { } catch (CommunicationException e) {
FailedLoginException ex = new FailedLoginException("Error contacting LDAP");
ex.initCause(e);
throw ex;
} catch (NamingException e) { } catch (NamingException e) {
if (context != null) { if (context != null) {
close(context); close(context);
} }
return false; FailedLoginException ex = new FailedLoginException("Error contacting LDAP");
ex.initCause(e);
throw ex;
} }
return true; return true;
@ -281,6 +300,12 @@ public class LDAPLoginModule implements LoginModule {
} else { } else {
constraints.setSearchScope(SearchControls.ONELEVEL_SCOPE); constraints.setSearchScope(SearchControls.ONELEVEL_SCOPE);
} }
if (log.isDebugEnabled()) {
log.debug("Get user roles.");
log.debug("Looking for the user roles in LDAP with ");
log.debug(" base DN: " + getLDAPPropertyValue(ROLE_BASE));
log.debug(" filter: " + filter);
}
NamingEnumeration<SearchResult> results = context.search(getLDAPPropertyValue(ROLE_BASE), filter, constraints); NamingEnumeration<SearchResult> results = context.search(getLDAPPropertyValue(ROLE_BASE), filter, constraints);
while (results.hasMore()) { while (results.hasMore()) {
SearchResult result = results.next(); SearchResult result = results.next();
@ -325,14 +350,22 @@ public class LDAPLoginModule implements LoginModule {
protected boolean bindUser(DirContext context, String dn, String password) throws NamingException { protected boolean bindUser(DirContext context, String dn, String password) throws NamingException {
boolean isValid = false; boolean isValid = false;
if (log.isDebugEnabled()) {
log.debug("Binding the user.");
}
context.addToEnvironment(Context.SECURITY_PRINCIPAL, dn); context.addToEnvironment(Context.SECURITY_PRINCIPAL, dn);
context.addToEnvironment(Context.SECURITY_CREDENTIALS, password); context.addToEnvironment(Context.SECURITY_CREDENTIALS, password);
try { try {
context.getAttributes("", null); context.getAttributes("", null);
isValid = true; isValid = true;
if (log.isDebugEnabled()) {
log.debug("User " + dn + " successfully bound.");
}
} catch (AuthenticationException e) { } catch (AuthenticationException e) {
isValid = false; isValid = false;
log.debug("Authentication failed for dn=" + dn); if (log.isDebugEnabled()) {
log.debug("Authentication failed for dn=" + dn);
}
} }
if (isLoginPropertySet(CONNECTION_USERNAME)) { if (isLoginPropertySet(CONNECTION_USERNAME)) {
@ -340,7 +373,6 @@ public class LDAPLoginModule implements LoginModule {
} else { } else {
context.removeFromEnvironment(Context.SECURITY_PRINCIPAL); context.removeFromEnvironment(Context.SECURITY_PRINCIPAL);
} }
if (isLoginPropertySet(CONNECTION_PASSWORD)) { if (isLoginPropertySet(CONNECTION_PASSWORD)) {
context.addToEnvironment(Context.SECURITY_CREDENTIALS, getLDAPPropertyValue(CONNECTION_PASSWORD)); context.addToEnvironment(Context.SECURITY_CREDENTIALS, getLDAPPropertyValue(CONNECTION_PASSWORD));
} else { } else {

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!-- START SNIPPET: xbean -->
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:amq="http://activemq.apache.org/schema/core"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd">
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"/>
<broker useJmx="false" xmlns="http://activemq.apache.org/schema/core" persistent="false">
<plugins>
<jaasAuthenticationPlugin configuration="OpenLdapConfiguration"/>
</plugins>
<transportConnectors>
<transportConnector uri="tcp://localhost:61616" />
</transportConnectors>
</broker>
</beans>
<!-- END SNIPPET: xbean -->

View File

@ -52,3 +52,27 @@ GuestLoginWithDefaults {
org.apache.activemq.jaas.GuestLoginModule required org.apache.activemq.jaas.GuestLoginModule required
debug=true; debug=true;
}; };
OpenLdapConfiguration {
org.apache.activemq.jaas.LDAPLoginModule required
debug=true
initialContextFactory=com.sun.jndi.ldap.LdapCtxFactory
connectionURL="ldap://localhost:389"
connectionUsername="cn=mqbroker,ou=Services,ou=system,dc=fusesource,dc=com"
connectionPassword="sunflower"
connectionProtocol="s"
topicSearchMatchingFormat="cn={0},ou=Topic,ou=Destination,ou=ActiveMQ,ou=system,dc=fusesource,dc=com"
topicSearchSubtreeBool=true
authentication=simple
userBase="ou=User,ou=ActiveMQ,ou=system,dc=fusesource,dc=com"
userSearchMatching="(uid={0})"
userSearchSubtree=false
roleSearchMatching="(uid={1})"
queueSearchMatchingFormat="cn={0},ou=Queue,ou=Destination,ou=ActiveMQ,ou=system,dc=fusesource,dc=com"
queueSearchSubtreeBool=true
roleBase="ou=Group,ou=ActiveMQ,ou=system,dc=fusesource,dc=com"
roleName=cn
roleSearchMatching="(member:=uid={1})"
roleSearchSubtree=tru
;
};