Hello Mathias,
I am new to scala and
spray.io. I am trying to implement LDAP custom authenticator. Please let me know if the below implementation is correct Thank you in advance.
ASUser.scala
------------
package com.as.utils
case class ASUser(username: String, password: String, role: String)
class AuthInfo(val user: ASUser) {
def hasPermission(permission: String) = {
true // Timebeing authorization is not handled.
}
}
ASLdapAuthenticator.scala
-------------------------
package com.as.utils
import javax.naming.directory.SearchControls
import spray.routing.authentication._
import spray.routing.directives.AuthMagnet
import scala.concurrent.duration.Duration
import scala.concurrent.{Await, ExecutionContext, Future}
object LDAP {
val asLdapAuthConfig = new LdapAuthConfig[ASUser] {
def contextEnv(user: String, pass: String): Seq[(String, String)] = {
Seq {
javax.naming.Context.PROVIDER_URL -> "ldap://localhost:10389"
}
}
var searchCredentials = "uid=admin,ou=system" -> "secret"
def searchBase(user: String) = {
"ou=people, o=pathstorm"
}
def searchFilter(user: String): String = {
"(uid=%s)" format user
}
def configureSearchControls(searchControls: SearchControls, user: String) = {
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE)
searchControls.setReturningAttributes(Array("givenName", "cn"))
}
def createUserObject(queryResult: LdapQueryResult): Option[ASUser] = {
Some(new ASUser(queryResult.name, queryResult.fullName, ""))
}
}
}
trait ASLdapAuthenticator {
def asLdapAuthenticator(implicit ec: ExecutionContext): AuthMagnet[AuthInfo] = {
def validateUser(userPass: Option[UserPass]): Future[Option[AuthInfo]] = {
import com.as.utils.LDAP.asLdapAuthConfig
LdapAuthenticator.apply(asLdapAuthConfig).apply(userPass).flatMap {
result => Future {
if (result != None) {
Option(new AuthInfo(result.get))
} else None
}
}
}
def authenticator(userPass: Option[UserPass]): Future[Option[AuthInfo]] = Future {
Await.result(validateUser(userPass), Duration.Inf)
}
BasicAuth(authenticator _, realm = "AS Private")
}
}
ASService.scala
---------------
get {
authenticate(asLdapAuthenticator) { authInfo =>
...
}
}