mattmar10 mattmar10 - 2 months ago 38
Scala Question

How to do authentication using Akka HTTP

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).


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.