Skip to content

Instantly share code, notes, and snippets.

@casualjim
Created October 3, 2011 23:35
Show Gist options
  • Select an option

  • Save casualjim/1260544 to your computer and use it in GitHub Desktop.

Select an option

Save casualjim/1260544 to your computer and use it in GitHub Desktop.
package backchat
package web
package auth
import model.User
import org.scalatra.auth.{ ScentryConfig, ScentrySupport }
import org.scalatra.ScalatraKernel
import org.scalatra.auth.strategy.BasicAuthSupport
/**
* Base trait for apps that need authentication support.
*
* @see [[backchat.model.User]]
*/
trait AuthenticationSupport extends ScentrySupport[User] with BasicAuthSupport[User] { self: ScalatraKernel ⇒
val realm = Config.serviceName
protected def contextPath = request.getContextPath
protected def fromSession = { case id: String ⇒ User.find(id) openOr null }
protected def toSession = { case usr: User ⇒ usr.id.toString }
protected val scentryConfig = (new ScentryConfig {}).asInstanceOf[ScentryConfiguration]
override protected def configureScentry {
scentry.unauthenticated {
scentry.strategies.get('BackchatHeader) foreach { _.unauthenticated() }
}
}
/**
* Registers authentication strategies.
*/
override protected def registerAuthStrategies = {
scentry.registerStrategy('BackchatHeader, app ⇒ new BackchatHeaderAuth(app))
}
}
package backchat
package web
package auth
import org.scalatra.auth.ScentryStrategy
import org.scalatra.ScalatraKernel
import model.User
class BackchatHeaderAuth(protected val app: ScalatraKernel, name: String) extends ScentryStrategy[User] {
override def isValid = true
def authenticateKey(key: String): Option[User] = User.authenticateWithApiKey(key).toOption
/**
* Authenticates a user by validating the key read from the authorization header.
*/
def authenticate() = {
BackchatHeaderAuth(app, name) flatMap (authenticateKey _)
}
/**
* Called when authentication failed. Sets a challenge header on the response.
*/
override def unauthenticated() {
val challenge = """%s realm="%s API""" format (name, name)
app.response.setHeader("WWW-Authenticate", challenge)
app.halt(401, "Unauthorized")
}
}
object BackchatHeaderAuth {
class OptionableString(s: String) {
def toOption = if(s == null || s.trim.isEmpty) None else Some(s)
}
private implicit def string2optionable(s: String) = new OptionableString(s)
def apply(app: ScalatraKernel, name: String) =
(app.request.getHeader("Authorization").toOption
map (_.trim)
filter (_.toUpperCase(ENGLISH).startsWith(name.toUpperCase(ENGLISH) + " "))
map (_.substring(name.length + 1)))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment