Authentication in Akka-Http

Hi All, In this blog, I will try to explain what is Authentication and why we need this and how you can do authentication in Akka HTTP

What is Authentication:- Authentication is the process of establishing a known identity for the user, whereby ‘identity’ is defined in the context of the application. This may be done with a username/password combination, a cookie, a pre-defined IP or some other mechanism. After authentication, the system believes that it knows who the user is.

Why Authentication:-  Authentication is a security mechanism designed to ensure that only authorized users can connect to a given service.
Authenticating both the user and the device can provide two-factor authentication (2FA). For a smartphone, there are apps that provide one-time password tokens, allowing the phone itself to serve as the physical device to satisfy the possession factor. The password response sent from the registered device verifies that the user is connecting from an authorized endpoint.

How Akka HTTP provides Authentication:- Akka HTTP uses the many prebuild SecurityDirectives for authenticating the users.

Let’s take an example of Bearer token authentication.
Most of the time what we do is, we write the code for authentication at a single place but perform the corresponding action on the basis of response of authentication in every route (if token is valid then fetch the users details by token and if not then send the response as bad request) we fetch the user details by token on every route but why ?

we should have a type of mechanism that, if the token is valid then the user data should be fetched at one place and provided to my routes and if the token is invalid then the request should be rejected from my authentication code, we don’t need to check the authentication response in every route.

So for handling that type of mechanism, Akka HTTP provides many directives, in these directives you just need to provide your authentication code for validating the token and if the token is invalid then just reject the request.

Let’s take an example of a directive extractCredentials that is used for extracting the credentials from the request headers

def authenticatedWithHeader: Directive1[User] =
  for {
    credentials <- extractCredentials
    result <- {
      credentials match {
        case Some(c) if c.scheme.equalsIgnoreCase("Bearer") => authenticate(c.token)
        case _ => rejectUnauthenticated(AuthenticationFailedRejection.CredentialsMissing)
      }
    }
  } yield result

In this code we get the token in the request header and check if it’s type is Bearer or not.
If it is Bearer type then we fetch the user and if it’s not then we reject the request by rejectUnauthenticated(AuthenticationFailedRejection.CredentialsMissing)

def authenticate(token: String): Directive1[User] = {
  validateAccessToken(token) match {
    case Some(user) => provide(user)
    case None => rejectUnauthenticated(AuthenticationFailedRejection.CredentialsRejected)
  }
}

def validateAccessToken(token):Option[User] = ??? // Your business logic that will fetch the user by Token

Let’s take an example that how you can call it from the route

val route =
      path("Authentication") {
          authenticated { user =>
           get {
            complete("This is authorized user")
        }
      }
    }

In this route authenticated will authenticate the user by the token and will provide it if the token is valid.

Hope this blog will help you more in authentication part. 🙂

knoldus-advt-sticker

Written by 

Shubham is a Software Consultant, with experience of more than 1.5 years.He is familiar with Object Oriented Programming Paradigms. He is always eager to learn new and advance concepts. Aside from being a programmer, his hobbies include playing badminton,watching movies, writing blogs. He has experience working in C, C++, CoreJava, Adv Java, HTML, CSS, JS, Ajax.

Leave a Reply

%d bloggers like this: