All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.gu.identity.play.OktaPlayAuthService.scala Maven / Gradle / Ivy

The newest version!
package com.gu.identity.play
import cats.effect.IO
import com.gu.identity.auth._
import play.api.mvc.RequestHeader

import scala.concurrent.ExecutionContext

// Class that builds upon functionality of OktaAuthService
// to make user authentication convenient in the context of a Play application.
// It handles extracting the user credentials from a Play request before authenticating them
// using the underlying OktaAuthServer.

class OktaPlayAuthService(oktaAuthService: OktaAuthService) {

  def oktaTokenFromAuthorizationHeader(requestHeader: RequestHeader): Either[ValidationError, String] =
    Helpers.fetchBearerTokenFromAuthHeader(requestHeader.headers.get)

  /** 

Returns the set of access claims on the given access token. Access tokens contain a set of claims that can be * used by API endpoints to carry out their processes: an example is a legacy Identity ID. The access token takes the * form of a JWT and when it's decoded it contains a Json access claim sub-object. We return this sub-object as a map * rather than a case class for maximum flexibility. The number of claims on the token will vary depending on the * access scopes that the token has been granted.

* *

This is a fast and lightweight method that makes no calls to the auth server. It's entirely dependent on the * access token given.

* *

If you are concerned that the token might be invalid, have been revoked or have expired, this method might not * be the most suitable.

*/ def getParsedClaimsLocallyFromRequest[A <: AccessClaims]( requestHeader: RequestHeader, requiredScopes: List[AccessScope], )(implicit accessClaimsParser: AccessClaimsParser[A]): Either[ValidationError, A] = for { token <- oktaTokenFromAuthorizationHeader(requestHeader) claims <- oktaAuthService.validateAccessTokenLocally(AccessToken(token), requiredScopes) } yield claims /**

Validates the given access token on the auth server that issued it and returns the set of access claims on the * given access token and also the identity claims returned by the auth server. The access claims will be those that * were on the token when it was issued so there is a possibility they will be out of date.

* *

There might be common values between the access claims and the identity claims but they won't necessarily have * the same names. They might also have different semantics so treat the identity claims with care and don't assume * that they can be used in place of particular access claims.

* *

If the token is invalid, has been revoked or has expired the response will fail at runtime with an * [[OktaValidationException]].

* *

This method makes a call on the auth server so only use it when necessary! If it's used too * often, the call will be rate-limited and performance will suffer.

*/ def getParsedClaimsFromServerValidatedAccessToken[I <: IdentityClaims, A <: AccessClaims]( requestHeader: RequestHeader, requiredScopes: List[AccessScope], )(implicit userInfoResponseParser: UserInfoResponseParser[I], accessClaimsParser: AccessClaimsParser[A] ): IO[CombinedClaims[I, A]] = { for { token <- IO.fromEither(oktaTokenFromAuthorizationHeader(requestHeader).left.map(OktaValidationException)) claims <- oktaAuthService.validateAccessTokenServerSide(AccessToken(token), requiredScopes) } yield claims } } object OktaPlayAuthService { def apply(config: OktaTokenValidationConfig)(implicit ec: ExecutionContext): OktaPlayAuthService = { val oktaAuthService = OktaAuthService(config) new OktaPlayAuthService(oktaAuthService) } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy