ktor icon indicating copy to clipboard operation
ktor copied to clipboard

Update LDAP Auth to return generic Principal

Open maarek opened this issue 7 years ago • 3 comments

LDAP Auth functions could be updated to return a generic Principal variant instead of UserIdPrincipal so that custom Principals could be returned from the builder functions and not require the expanded ldapAuthenticate(K, String, (MutableMap<String, Any?>) -> Unit, InitialDirContext.(K) -> P?): P?

maarek avatar Apr 02 '18 14:04 maarek

This issue has been automatically marked as stale because it has not had recent activity.

stale[bot] avatar Sep 24 '19 14:09 stale[bot]

Please check the following ticket on YouTrack for follow-ups to this issue. GitHub issues will be closed in the coming weeks.

oleg-larshin avatar Aug 10 '20 15:08 oleg-larshin

Yes please! I need to return custom LDAP user attributes from the ldapAuthenticate method. I was a bit surprised I could only return their name...

Also, consider adding this function, ldapSearch so that you can perform searches for ldap user roles. I had to create this method myself, but luckilly all of these imports are in the standard library:

fun ldapSearch(
    credential: UserPasswordCredential,
    ldapServerURL: String,
    baseDN: String,
    filter: String,
    attributes: Array<String>
): NamingEnumeration<SearchResult> {
    val env = Hashtable<String, String>()
    env[Context.INITIAL_CONTEXT_FACTORY] = "com.sun.jndi.ldap.LdapCtxFactory"
    env[Context.PROVIDER_URL] = ldapServerURL
    env[Context.SECURITY_AUTHENTICATION] = "simple"
    env[Context.SECURITY_PRINCIPAL] = "cn=${credential.name},dc=myOrg,dc=com" // May need to change this. it's hard coded.
    env[Context.SECURITY_CREDENTIALS] = credential.password

    val context = InitialDirContext(env)

    val controls = SearchControls()
    controls.searchScope = SearchControls.SUBTREE_SCOPE
    controls.returningAttributes = attributes

    return context.search(baseDN, filter, controls)
}

I use it like this:

val searchResults = ldapSearch(bindAdmin, "ldap://0.0.0.0:389", "ou=Employees,dc=myOrg,dc=com", "(cn=${credentials.name})", arrayOf("cn", "sn", "mail")).toList()

val userRoles = ldapSearch(bindAdmin, "ldap://0.0.0.0:389", "ou=Roles,dc=myOrg,dc=com",   "(roleOccupant=cn=${credentials.name},ou=Employees,dc=myOrg,dc=com)", arrayOf("cn")).toList()

But unfortunately I can't return any of this information because only UserIdPrincipal is allowed to be returned...

Edit: found a bit of a hacky way around this:

basic("ldap") {
  validate { credentials ->
     var ldapUserSession: SomeCustomClassExtendingPrincipal? = null

    ldapAuthenticate() { /* Set the ldapUserSession in here */ }

   return ldapUserSession

QuinnBast avatar Aug 14 '24 19:08 QuinnBast