mirror of https://github.com/apache/activemq.git
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:
parent
b5579ac1ca
commit
e1ce619872
|
@ -131,17 +131,11 @@ 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();
|
|
||||||
} else {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
|
||||||
throw (LoginException)new LoginException("LDAP Error").initCause(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean logout() throws LoginException {
|
public boolean logout() throws LoginException {
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
if (log.isDebugEnabled()) {
|
||||||
|
log.debug("Create the LDAP initial context.");
|
||||||
|
}
|
||||||
|
try {
|
||||||
context = open();
|
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,22 +350,29 @@ 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;
|
||||||
|
if (log.isDebugEnabled()) {
|
||||||
log.debug("Authentication failed for dn=" + dn);
|
log.debug("Authentication failed for dn=" + dn);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (isLoginPropertySet(CONNECTION_USERNAME)) {
|
if (isLoginPropertySet(CONNECTION_USERNAME)) {
|
||||||
context.addToEnvironment(Context.SECURITY_PRINCIPAL, getLDAPPropertyValue(CONNECTION_USERNAME));
|
context.addToEnvironment(Context.SECURITY_PRINCIPAL, getLDAPPropertyValue(CONNECTION_USERNAME));
|
||||||
} 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 {
|
||||||
|
|
|
@ -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 -->
|
|
@ -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
|
||||||
|
;
|
||||||
|
};
|
||||||
|
|
Loading…
Reference in New Issue