-
Notifications
You must be signed in to change notification settings - Fork 718
/
LDAPAuthService.scala
69 lines (58 loc) · 2.47 KB
/
LDAPAuthService.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
package controllers.auth.ldap
import java.util.Hashtable
import com.google.inject.Inject
import com.sun.jndi.ldap.LdapCtxFactory
import controllers.auth.AuthService
import javax.naming._
import javax.naming.directory.SearchControls
import play.api.{Configuration, Logger}
import scala.util.control.NonFatal
class LDAPAuthService @Inject()(globalConfig: Configuration) extends AuthService {
private val log = Logger(this.getClass)
private final val config = new LDAPAuthConfig(globalConfig.get[Configuration]("auth.settings"))
def checkUserAuth(username: String, password: String): Boolean = {
val props = new Hashtable[String, String]()
props.put(Context.SECURITY_PRINCIPAL, config.userTemplate.format(username, config.baseDN))
props.put(Context.SECURITY_CREDENTIALS, password)
try {
LdapCtxFactory.getLdapCtxInstance(config.url, props)
true
} catch {
case e: AuthenticationException =>
log.info(s"login of $username failed with: ${e.getMessage}")
false
case NonFatal(e) =>
log.error(s"login of $username failed", e)
false
}
}
def checkGroupMembership(username: String, groupConfig: LDAPGroupSearchConfig): Boolean = {
val props = new Hashtable[String, String]()
props.put(Context.SECURITY_PRINCIPAL, groupConfig.bindDN)
props.put(Context.SECURITY_CREDENTIALS, groupConfig.bindPwd)
props.put(Context.REFERRAL, "follow")
val user = groupConfig.userAttrTemplate.format(username, config.baseDN)
val controls = new SearchControls()
controls.setSearchScope(SearchControls.SUBTREE_SCOPE)
try {
val context = LdapCtxFactory.getLdapCtxInstance(config.url, props)
val search = context.search(groupConfig.baseDN,s"(& (${groupConfig.userAttr}=$user)(${groupConfig.group}))", controls)
context.close()
search.hasMore()
} catch {
case e: AuthenticationException =>
log.info(s"User $username doesn't fulfill condition (${groupConfig.group}) : ${e.getMessage}")
false
case NonFatal(e) =>
log.error(s"Unexpected error while checking group membership of $username", e)
false
}
}
def auth(username: String, password: String): Option[String] = {
val isValidUser = config.groupMembership match {
case Some(groupConfig) => checkGroupMembership(username, groupConfig) && checkUserAuth(username, password)
case None => checkUserAuth(username, password)
}
if (isValidUser) Some(username) else None
}
}