Just a heads up: On March 24, 2025, starting at 4:30pm CDT / 19:30 UTC, the site will be undergoing scheduled maintenance for a few hours. During this time, the site might be unavailable for a short while. Thanks for your patience.
×I use Scriptrunner to run an LDAP query against the underlying "AuthoritativeDirectory" defined for a JIRA User directory with delegated LDAP authentication.
The following code works on JIRA 6.4.x, but fails on 7.4 (on a different machine) with
ClassNotFoundException: com.atlassian.crowd.directory.ssl.LdapHostnameVerificationSSLSocketFactory
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.crowd.embedded.api.CrowdDirectoryService
import com.atlassian.crowd.embedded.api.Directory
// https://docs.atlassian.com/atlassian-crowd/3.1.2/com/atlassian/crowd/directory/RemoteDirectory.html
import com.atlassian.crowd.directory.RemoteDirectory // interface
import com.atlassian.crowd.search.builder.QueryBuilder
import com.atlassian.crowd.search.builder.Restriction
import com.atlassian.crowd.search.query.entity.restriction.constants.UserTermKeys
import com.atlassian.crowd.search.EntityDescriptor
import com.atlassian.crowd.embedded.api.User
// https://docs.atlassian.com/atlassian-crowd/3.1.2/com/atlassian/crowd/directory/GenericLDAP.html
import com.atlassian.crowd.directory.GenericLDAP
// https://docs.atlassian.com/atlassian-crowd/3.1.2/com/atlassian/crowd/directory/DelegatedAuthenticationDirectory.html
import com.atlassian.crowd.directory.DelegatedAuthenticationDirectory
import com.atlassian.crowd.directory.loader.DelegatedAuthenticationDirectoryInstanceLoader // interface
import com.atlassian.crowd.directory.ssl.LdapHostnameVerificationSSLSocketFactory
def dirsvc = ComponentAccessor.getComponent(CrowdDirectoryService)
def dirs = dirsvc.findAllDirectories()
Directory mydirdef = dirs[0] // top-most one is mydir
def dir = ComponentAccessor.getComponent(DelegatedAuthenticationDirectoryInstanceLoader)
RemoteDirectory mydir = dir.getDirectory(mydirdef)
mydir.getClass() // -> DelegatedAuthenticationDirectory
mydir.getKeys() // all config-keys (from the directory definition)
def qry = QueryBuilder.queryFor(User.class, EntityDescriptor.user()).with(
Restriction.on(UserTermKeys.LAST_NAME).startingWith("berg")
).returningAtMost(10)
def users = mydir.searchUsers(qry) // searches ONLY within the directory, not in LDAP :-(
def ldap = mydir.getAuthoritativeDirectory() // com.atlassian.crowd.directory.GenericLDAP
def users2 = ldap.searchUsers(qry) // searches in underlying LDAP directory
org.springframework.transaction.CannotCreateTransactionException: Could not create DirContext instance for transaction;
nested exception is org.springframework.ldap.CommunicationException: hostname.some.corp:636;
nested exception is javax.naming.CommunicationException: hostname.some.corp:636
[Root exception is java.lang.ClassNotFoundException: com.atlassian.crowd.directory.ssl.LdapHostnameVerificationSSLSocketFactory]
I solved the problem with the missing class by adding this code:
import com.atlassian.crowd.directory.ssl.LdapHostnameVerificationSSLSocketFactory
Thread currentThread = Thread.currentThread();
ClassLoader classLoader= currentThread.getContextClassLoader();
currentThread.setContextClassLoader(LdapHostnameVerificationSSLSocketFactory.class.getClassLoader());
Are you using java 7?
com.atlassian.crowd.directory.ssl.LdapHostnameVerificationSSLSocketFactory is not present in the jira api.
import package com.atlassian.crowd.directory.ssl should resolve this, if the class really exists.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I am using jdk1.8.0_91, Java 8 being required for JIRA 7.4 (or possibly just tomcat)
The API doc is at https://docs.atlassian.com/atlassian-crowd/2.10.2/com/atlassian/crowd/directory/ssl/LdapHostnameVerificationSSLSocketFactory.html
The additional import statement does not change anything; I already imported the class LdapHostnameVerificationSSLSocketFactory from that package.
It is really strange, because JIRA correctly authenticates against the LDAPs server! It is just Groovy which bails out. Worse, I have identified ./atlassian-jira/WEB-INF/lib/crowd-ldap-2.10.2-rc04.jar as containing this package along with others which do import without a hitch.
Could it be something entirely different, the "Root Exception" not being the root cause? Configuration to verify (or not) LDAP server identity?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I guess the import package statement should be in the crowd plugin. update the plugin and try again.
So you can successfully test the AD connection from jira?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Google found some useful bits of information:
This issue appeared first as https://jira.atlassian.com/browse/JRASERVER-27347 (fixed in 6.0.0) and later as https://jira.atlassian.com/browse/JRASERVER-42868 ("resolved" but not fixed in 6.2.6). For me it works in 6.4.4, but not in 7.4.2 -- kind of ON/OFF story.
It seems that it is still lurking somewhere....
I filed a support request with Atlassian to find out if it is possible to replace just the crowd plugin (mind you, this is embedded crowd) and from where would I get the plugin.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Did you get this working?
I get the same error when trying to remove a user from a group with Groovy/Scriptrunner. Also using LDAPS.
Root exception is java.lang.ClassNotFoundException: com.atlassian.crowd.directory.ssl.LdapHostnameVerificationSSLSocketFactory
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I'm seeing the same problem too. Did you ever find a solution for this?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Check out this, I have it running in my code.
List liste = []
try {
listGrupperNavn = ComponentAccessor.getGroupManager().getGroupNamesForUser(appUser)
listGrupperNavn.each {
try {
log.debug "ITSOS 2.0 - Group to remove: " + it.toString()
Group fjernGruppe = groupManager.getGroup(it.toString())
if(groupManager.groupExists(it.toString()) == false) {
log.debug "ITSOS 2.0 - Gruppen finnes ikke."
} else {
if (it.toString() == "S4B-IncludeGroup" || it.toString() == "S4B-UserContainingGroup") { //
log.debug "ITSOS 2.0 - Fjerner ikke denne gruppen: " + it.toString()
} else {
//log.debug "ITSOS 2.0 - Fjerner denne gruppen: " + it.toString()
liste.add(it.toString())
}
}
} catch (com.atlassian.crowd.exception.runtime.GroupNotFoundException gnfe) {
log.error "ITSOS 2.0 - Finner ikke gruppen i AD - Feil i fjernTilganger: " + gnfe.toString()
}
} // End each
log.debug "ITSOS 2.0 - Grupper som skal fjernes fra bruker: " + liste.toString()
mapper = new GroupRemoveChildMapper()// listGrupper
mapper.register(SAM, liste)
context = new JiraServiceContextImpl(sysUser); // user which removes another user to a group
resultRemoveUserFromGroups = groupService.validateRemoveUserFromGroups(context, liste, SAM)
if (resultRemoveUserFromGroups == true) {
log.debug "ITSOS 2.0 - Skal fjerne gruppemedlemskap..."
groupService.removeUsersFromGroups(context, mapper)
log.debug "ITSOS 2.0 - Gruppemedlemskap fjernet OK."
UserMessageUtil.success("Tilgangene på bruker " + appUser + " er fjernet i AD.")
resultFjernTilganger = true
}
}
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I got slightly further, but no solution yet.
For my external directory provider defined as "GenericLDAP" (some commercial enterprise product I do not know), the code fails. But I have another one based on OpenLDAP, and that works!
The difference is that the method `mydir.getAuthoritativeDirectory()` in the code of my first post returns a `com.atlassian.crowd.directory.GenericLDAP` object in the first case, and `OpenLDAP` in the latter. Surprisingly "GenericLDAP" is actually a subclass of "OpenLDAP" (I would have expected the other way round).
I will check if the directory definition for the corporate LDAP also works when I base it on OpenLDAP, that would then be a work-around.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Atlassian Government Cloud has achieved FedRAMP Authorization at the Moderate level! Join our webinar to learn how you can accelerate mission success and move work forward faster in cloud, all while ensuring your critical data is secure.
Register Now
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.