How to do authentication using Akka HTTP

mattmar10 picture mattmar10 · Oct 18, 2015 · Viewed 7.1k times · Source

Looking for a good explanation on how to do authentication using akka HTTP. Given a route that looks like

val route = 
  path("account") {
    authenticateBasic(realm = "some realm", myAuthenticator) { user =>
      get {
        encodeResponseWith(Deflate) {
          complete {
            //do something here
          }
        }
      }
    }
  }

The documentation outlines a way, but then the pertinent part performing the actual authentication is omitted...

// backend entry points
def myAuthenticator: Authenticator[User] = ???

Where can I find an example implementation of such an authenticator? I have the logic already for authenticating a user given a user name and password, but what i can't figure out is how to get a username/password (or token containing both) from the HTTP request (or RequestContext).

Answer

dk14 picture dk14 · Oct 19, 2015

Authenticator is just a function UserCredentials => Option[T], where UserCredentials in case of being (check with pattern matching) Provided have verifySecret(secret) method which you need to safely call and return Some (Some user for example) in case of success, like:

def myAuthenticator: Authenticator[User] = {
  case p@Provided(username) =>
    if(p.verifySecret(myGetSecret(username))) Some(username) else None
  case Missing => None //you can throw an exeption here to get customized response otherwise it will be regular `CredentialsMissing` message

}   

myGetSecret is your custom function which gets username and returns your secret (e.g. password), getting it possibly from database. verifySecret will securely compare (to avoid timing attack) provided password with your password from myGetSecret. Generally, "secret" is any hidden information (like hash of credentials or token) but in case of basic authentication it is just a plain password extracted from http headers.

If you need more customized approach - use authenticateOrRejectWithChallenge that gets HttpCredentials as an input, so you can extract provided password from there.

More info about authorization is in scaladocs.