mirror of
https://github.com/gitbucket/gitbucket.git
synced 2025-11-05 13:05:50 +01:00
LDAP authentication by using bind account
This commit is contained in:
committed by
Tomofumi Tanaka
parent
b9aa6a234b
commit
bfc1d1d6b0
@@ -2,49 +2,107 @@ package util
|
||||
|
||||
import service.SystemSettingsService.Ldap
|
||||
import service.SystemSettingsService
|
||||
import com.novell.ldap.LDAPConnection
|
||||
import com.novell.ldap.{LDAPReferralException, LDAPEntry, LDAPConnection}
|
||||
|
||||
/**
|
||||
* Utility for LDAP authentication.
|
||||
*/
|
||||
object LDAPUtil extends App {
|
||||
object LDAPUtil {
|
||||
|
||||
private val LDAP_VERSION: Int = 3
|
||||
|
||||
/**
|
||||
* Try authentication by LDAP using given configuration.
|
||||
* Returns Right(mailAddress) if authentication is successful, otherwise Left(errorMessage).
|
||||
*/
|
||||
def authenticate(ldapSettings: Ldap, userName: String, password: String): Either[String, String] = {
|
||||
var conn: LDAPConnection = null
|
||||
try {
|
||||
conn = new LDAPConnection()
|
||||
conn.connect(ldapSettings.host, ldapSettings.port.getOrElse(SystemSettingsService.DefaultLdapPort))
|
||||
val userDN = ldapSettings.userNameAttribute + "=" + userName + ",ou=Users," + ldapSettings.baseDN
|
||||
conn.bind(3, userDN, password.getBytes)
|
||||
if(conn.isBound){
|
||||
val results = conn.search(userDN, LDAPConnection.SCOPE_BASE, "", Array[String](ldapSettings.mailAttribute), false)
|
||||
var mailAddress: String = null
|
||||
while(results.hasMore){
|
||||
mailAddress = results.next.getAttribute(ldapSettings.mailAttribute).getStringValue
|
||||
bind(
|
||||
ldapSettings.host,
|
||||
ldapSettings.port.getOrElse(SystemSettingsService.DefaultLdapPort),
|
||||
ldapSettings.bindDN,
|
||||
ldapSettings.bindPassword
|
||||
) match {
|
||||
case Some(conn) => {
|
||||
withConnection(conn) { conn =>
|
||||
findUser(conn, userName, ldapSettings.baseDN, ldapSettings.userNameAttribute) match {
|
||||
case Some(userDN) => userAuthentication(ldapSettings, userDN, password)
|
||||
case None => Left("User does not exist")
|
||||
}
|
||||
}
|
||||
if(mailAddress != null){
|
||||
Right(mailAddress)
|
||||
} else {
|
||||
Left("Can't find mail address.")
|
||||
}
|
||||
} else {
|
||||
Left("Authentication failed.")
|
||||
}
|
||||
case None => Left("System LDAP authentication failed.")
|
||||
}
|
||||
}
|
||||
|
||||
private def userAuthentication(ldapSettings: Ldap, userDN: String, password: String): Either[String, String] = {
|
||||
bind(
|
||||
ldapSettings.host,
|
||||
ldapSettings.port.getOrElse(SystemSettingsService.DefaultLdapPort),
|
||||
userDN,
|
||||
password
|
||||
) match {
|
||||
case Some(conn) => {
|
||||
withConnection(conn) { conn =>
|
||||
findMailAddress(conn, userDN, ldapSettings.mailAttribute) match {
|
||||
case Some(mailAddress) => Right(mailAddress)
|
||||
case None => Left("Can't find mail address.")
|
||||
}
|
||||
}
|
||||
}
|
||||
case None => Left("User LDAP Authentication Failed.")
|
||||
}
|
||||
}
|
||||
|
||||
private def bind(host: String, port: Int, dn: String, password: String): Option[LDAPConnection] = {
|
||||
val conn: LDAPConnection = new LDAPConnection
|
||||
try {
|
||||
conn.connect(host, port)
|
||||
conn.bind(LDAP_VERSION, dn, password.getBytes)
|
||||
Some(conn)
|
||||
} catch {
|
||||
case ex: Exception => Left(ex.getMessage)
|
||||
} finally {
|
||||
if(conn != null){
|
||||
conn.disconnect()
|
||||
case e: Exception => {
|
||||
if (conn.isConnected) conn.disconnect()
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// val ldapSettings = Ldap("192.168.159.128", 389, "dc=unix-power,dc=net", "uid", "mail")
|
||||
//
|
||||
// println(authenticate(ldapSettings, "tanaka", "password"))
|
||||
private def withConnection[T](conn: LDAPConnection)(f: LDAPConnection => T): T = {
|
||||
try {
|
||||
f(conn)
|
||||
} finally {
|
||||
conn.disconnect()
|
||||
}
|
||||
}
|
||||
|
||||
private def findUser(conn: LDAPConnection, userName: String, baseDN: String, userNameAttribute: String): Option[String] = {
|
||||
val results = conn.search(baseDN, LDAPConnection.SCOPE_SUB, userNameAttribute + "=" + userName, null, false)
|
||||
while (results.hasMore) {
|
||||
var entry: LDAPEntry = null
|
||||
try {
|
||||
entry = results.next
|
||||
} catch {
|
||||
case lre: LDAPReferralException => // NOTE(tanacasino): Referral follow is off. so ignores it.(for AD)
|
||||
}
|
||||
if (entry != null) {
|
||||
return Some(entry.getDN)
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
private def findMailAddress(conn: LDAPConnection, userDN: String, mailAttribute: String): Option[String] = {
|
||||
val attributes = Array[String](mailAttribute)
|
||||
val results = conn.search(userDN, LDAPConnection.SCOPE_BASE, null, attributes, false)
|
||||
if (results.hasMore) {
|
||||
val attr = results.next.getAttribute(mailAttribute)
|
||||
if (attr != null) {
|
||||
Some(attr.getStringValue)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user