org.http4s.headers.Authorization Scala Examples
The following examples show how to use org.http4s.headers.Authorization.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example.
Example 1
Source File: HmacAuthMiddleware.scala From iotchain with MIT License | 5 votes |
package jbok.network.http.server.middleware import java.time.{Duration, Instant} import cats.data.{Kleisli, OptionT} import cats.effect.Sync import jbok.network.http.server.authentication.HMAC import org.http4s.headers.Authorization import org.http4s.util.CaseInsensitiveString import org.http4s.{AuthScheme, Credentials, HttpRoutes, Request, Response, Status} import tsec.mac.jca.{HMACSHA256, MacSigningKey} import scala.concurrent.duration.{FiniteDuration, _} sealed abstract class HmacAuthError(val message: String) extends Exception(message) object HmacAuthError { case object NoAuthHeader extends HmacAuthError("Could not find an Authorization header") case object NoDatetimeHeader extends HmacAuthError("Could not find an X-Datetime header") case object BadMAC extends HmacAuthError("Bad MAC") case object InvalidMacFormat extends HmacAuthError("The MAC is not a valid Base64 string") case object InvalidDatetime extends HmacAuthError("The datetime is not a valid UTC datetime string") case object Timeout extends HmacAuthError("The request time window is closed") } object HmacAuthMiddleware { val defaultDuration: FiniteDuration = 5.minutes private def verifyFromHeader[F[_]]( req: Request[F], key: MacSigningKey[HMACSHA256], duration: FiniteDuration ): Either[HmacAuthError, Unit] = for { authHeader <- req.headers .get(Authorization) .flatMap { t => t.credentials match { case Credentials.Token(scheme, token) if scheme == AuthScheme.Bearer => Some(token) case _ => None } } .toRight(HmacAuthError.NoAuthHeader) datetimeHeader <- req.headers .get(CaseInsensitiveString("X-Datetime")) .toRight(HmacAuthError.NoDatetimeHeader) instant <- HMAC.http.verifyFromHeader( req.method.name, req.uri.renderString, datetimeHeader.value, authHeader, key ) _ <- Either.cond( Instant.now().isBefore(instant.plus(Duration.ofNanos(duration.toNanos))), (), HmacAuthError.Timeout ) } yield () def apply[F[_]: Sync](key: MacSigningKey[HMACSHA256], duration: FiniteDuration = defaultDuration)(routes: HttpRoutes[F]): HttpRoutes[F] = Kleisli { req: Request[F] => verifyFromHeader(req, key, duration) match { case Left(error) => OptionT.some[F](Response[F](Status.Forbidden).withEntity(error.message)) case Right(_) => routes(req) } } }
Example 2
Source File: HmacAuthMiddlewareSpec.scala From iotchain with MIT License | 5 votes |
package jbok.network.http.server.middleware import java.time.Instant import cats.Id import cats.effect.IO import cats.implicits._ import jbok.common.CommonSpec import jbok.network.http.server.authentication.HMAC import org.http4s.dsl.io._ import org.http4s.headers.Authorization import org.http4s.implicits._ import org.http4s.{AuthScheme, Credentials, Header, HttpRoutes, Request, Status, Uri} import scodec.bits.ByteVector import tsec.mac.jca.{HMACSHA256, MacSigningKey} import scala.concurrent.duration._ class HmacAuthMiddlewareSpec extends CommonSpec { "HmacAuthMiddleware" should { val key = HMACSHA256.buildKey[Id]( ByteVector.fromValidHex("70ea14ac30939a972b5a67cab952d6d7d474727b05fe7f9283abc1e505919e83").toArray ) def sign(url: String): (String, String) = { val datetime = Instant.now().toString val signature = HMAC.http.signForHeader("GET", url, datetime, key).unsafeRunSync() (signature, datetime) } val routes = HttpRoutes.of[IO] { case GET -> Root / "ping" => Ok("pong") } val service = routes.orNotFound val req = Request[IO](uri = Uri.uri("/ping")) service.run(req).unsafeRunSync().status shouldBe Status.Ok val authedService = HmacAuthMiddleware(key)(routes).orNotFound "403 if no Authorization header" in { val resp = authedService.run(req).unsafeRunSync() val text = resp.bodyAsText.compile.foldMonoid.unsafeRunSync() resp.status shouldBe Status.Forbidden text shouldBe HmacAuthError.NoAuthHeader.message } "403 if no X-Datetime header" in { val signature = HMAC.http.signForHeader("GET", "/ping", Instant.now().toString, key).unsafeRunSync() val req = Request[IO](uri = Uri.uri("/ping")).putHeaders(Authorization(Credentials.Token(AuthScheme.Bearer, signature))) val resp = authedService.run(req).unsafeRunSync() val text = resp.bodyAsText.compile.foldMonoid.unsafeRunSync() resp.status shouldBe Status.Forbidden text shouldBe HmacAuthError.NoDatetimeHeader.message } "403 if time window is closed" in { val authedService = HmacAuthMiddleware(key, 2.seconds)(routes).orNotFound val now = Instant.now() val signature = HMAC.http.signForHeader("GET", "/ping", now.toString, key).unsafeRunSync() val req = Request[IO](uri = Uri.uri("/ping")) .putHeaders( Authorization(Credentials.Token(AuthScheme.Bearer, signature)), Header("X-Datetime", now.toString) ) val resp = authedService.run(req).unsafeRunSync() resp.status shouldBe Status.Ok IO.sleep(3.seconds).unsafeRunSync() val resp2 = authedService.run(req).unsafeRunSync() val text = resp2.bodyAsText.compile.foldMonoid.unsafeRunSync() resp2.status shouldBe Status.Forbidden text shouldBe HmacAuthError.Timeout.message } "helper" in { val (sig, date) = sign("/v1/blocks") println(("Authorization", s"Bearer $sig")) println(("X-Datetime", date)) println(("Random key", ByteVector(MacSigningKey.toJavaKey[HMACSHA256](HMACSHA256.generateKey[Id]).getEncoded).toHex)) } } }
Example 3
Source File: BearerTokenAuthenticatorTests.scala From tsec with MIT License | 5 votes |
package tsec.authentication import java.time.Instant import cats.effect.IO import org.http4s.headers.Authorization import org.http4s.{AuthScheme, Credentials, Request} import tsec.common.SecureRandomId import scala.concurrent.duration._ class BearerTokenAuthenticatorTests extends RequestAuthenticatorSpec { def timeoutAuthSpecTester: AuthSpecTester[TSecBearerToken[Int]] = { val tokenStore: BackingStore[IO, SecureRandomId, TSecBearerToken[Int]] = dummyBackingStore[IO, SecureRandomId, TSecBearerToken[Int]](s => SecureRandomId.coerce(s.id)) val dummyStore = dummyBackingStore[IO, Int, DummyUser](_.id) val settings = TSecTokenSettings(10.minutes, Some(10.minutes)) val authenticator = BearerTokenAuthenticator(tokenStore, dummyStore, settings) new AuthSpecTester[TSecBearerToken[Int]](authenticator, dummyStore) { def embedInRequest(request: Request[IO], authenticator: TSecBearerToken[Int]): Request[IO] = request.putHeaders(Authorization(Credentials.Token(AuthScheme.Bearer, authenticator.id))) def expireAuthenticator(b: TSecBearerToken[Int]): IO[TSecBearerToken[Int]] = authenticator.update(b.copy(expiry = Instant.now.minusSeconds(30))) def timeoutAuthenticator(b: TSecBearerToken[Int]): IO[TSecBearerToken[Int]] = authenticator.update(b.copy(lastTouched = Some(Instant.now.minusSeconds(300000)))) def wrongKeyAuthenticator: IO[TSecBearerToken[Int]] = IO.pure(TSecBearerToken(SecureRandomId.Interactive.generate, -20, Instant.now(), None)) } } AuthenticatorTest("Bearer token authenticator", timeoutAuthSpecTester) requestAuthTests[TSecBearerToken[Int]]("Bearer token Request handler", timeoutAuthSpecTester) }
Example 4
Source File: BasicAuthentication.scala From endpoints4s with MIT License | 5 votes |
package endpoints4s.http4s.client import endpoints4s.{Tupler, algebra} import endpoints4s.algebra.BasicAuthentication.Credentials import endpoints4s.algebra.Documentation import org.http4s.headers.Authorization import org.http4s.BasicCredentials trait BasicAuthentication extends algebra.BasicAuthentication { self: EndpointsWithCustomErrors => private[endpoints4s] def authenticatedRequest[U, E, H, UE, HCred, Out]( method: Method, url: Url[U], entity: RequestEntity[E], headers: RequestHeaders[H], requestDocs: Documentation )(implicit tuplerUE: Tupler.Aux[U, E, UE], tuplerHCred: Tupler.Aux[H, Credentials, HCred], tuplerUEHCred: Tupler.Aux[UE, HCred, Out] ): Request[Out] = { val basicAuthenticationHeader: RequestHeaders[Credentials] = (credentials, request) => { request.putHeaders( Authorization( BasicCredentials(credentials.username, credentials.password) ) ) } request( method, url, entity, requestDocs, headers ++ basicAuthenticationHeader ) } }
Example 5
Source File: RestKeyMiddlewareSpec.scala From pizza-auth-3 with MIT License | 5 votes |
package moe.pizza.auth.webapp.rest import org.http4s._ import org.http4s.dsl._ import org.http4s.headers.Authorization import org.http4s.util.Writer import org.scalatest.{FlatSpec, MustMatchers} class RestKeyMiddlewareSpec extends FlatSpec with MustMatchers { val emptyservice = HttpService { case req @ GET -> Root => Ok("inner service") } val svc = new RestKeyMiddleware(List("key1", "key2")).apply(emptyservice) "when wrapping a service it" should "pass through calls with valid keys" in { val r = svc .apply( new Request(uri = Uri.uri("/"), headers = Headers(new Authorization(OAuth2BearerToken("key1"))))) .run r.status must equal(Ok) } "when wrapping a service it" should "fail calls without valid keys" in { val r = svc .apply( new Request(uri = Uri.uri("/"), headers = Headers(new Authorization(OAuth2BearerToken("key3"))))) .run r.status must equal(Unauthorized) } }
Example 6
Source File: KubeConfig.scala From kubernetes-client with Apache License 2.0 | 5 votes |
package com.goyeau.kubernetes.client import java.io.File import cats.effect.Sync import com.goyeau.kubernetes.client.util.Yamls import io.chrisdavenport.log4cats.Logger import org.http4s.Uri import org.http4s.headers.Authorization case class KubeConfig( server: Uri, authorization: Option[Authorization] = None, caCertData: Option[String] = None, caCertFile: Option[File] = None, clientCertData: Option[String] = None, clientCertFile: Option[File] = None, clientKeyData: Option[String] = None, clientKeyFile: Option[File] = None, clientKeyPass: Option[String] = None ) { require(caCertData.isEmpty || caCertFile.isEmpty, "caCertData and caCertFile can't be set at the same time") require( clientCertData.isEmpty || clientCertFile.isEmpty, "clientCertData and clientCertFile can't be set at the same time" ) } object KubeConfig { @deprecated(message = "Use fromFile instead", since = "0.4.1") def apply[F[_]: Sync: Logger](kubeconfig: File): F[KubeConfig] = fromFile(kubeconfig) def fromFile[F[_]: Sync: Logger](kubeconfig: File): F[KubeConfig] = Yamls.fromKubeConfigFile(kubeconfig, None) @deprecated(message = "Use fromFile instead", since = "0.4.1") def apply[F[_]: Sync: Logger](kubeconfig: File, contextName: String): F[KubeConfig] = fromFile(kubeconfig, contextName) def fromFile[F[_]: Sync: Logger](kubeconfig: File, contextName: String): F[KubeConfig] = Yamls.fromKubeConfigFile(kubeconfig, Option(contextName)) }
Example 7
Source File: LoginTest.scala From scala-pet-store with Apache License 2.0 | 5 votes |
package io.github.pauljamescleary.petstore package infrastructure.endpoint import cats.data.Kleisli import cats.effect.IO import domain.authentication.{LoginRequest, SignupRequest} import domain.users.{Role, User} import org.http4s.circe.{jsonEncoderOf, jsonOf} import org.http4s.client.dsl.Http4sClientDsl import org.http4s.{EntityDecoder, EntityEncoder, HttpApp, Request, Response} import org.http4s.implicits._ import org.http4s.headers.Authorization import io.circe.generic.auto._ import org.http4s.dsl.Http4sDsl trait LoginTest extends Http4sClientDsl[IO] with Http4sDsl[IO] { implicit val userEnc: EntityEncoder[IO, User] = jsonEncoderOf implicit val userDec: EntityDecoder[IO, User] = jsonOf implicit val signUpRequestEnc: EntityEncoder[IO, SignupRequest] = jsonEncoderOf implicit val signUpRequestDec: EntityDecoder[IO, SignupRequest] = jsonOf implicit val loginRequestEnc: EntityEncoder[IO, LoginRequest] = jsonEncoderOf implicit val loginRequestDec: EntityDecoder[IO, LoginRequest] = jsonOf def signUpAndLogIn( userSignUp: SignupRequest, userEndpoint: HttpApp[IO], ): IO[(User, Option[Authorization])] = for { signUpRq <- POST(userSignUp, uri"/users") signUpResp <- userEndpoint.run(signUpRq) user <- signUpResp.as[User] loginBody = LoginRequest(userSignUp.userName, userSignUp.password) loginRq <- POST(loginBody, uri"/users/login") loginResp <- userEndpoint.run(loginRq) } yield { user -> loginResp.headers.get(Authorization) } def signUpAndLogInAsAdmin( userSignUp: SignupRequest, userEndpoint: Kleisli[IO, Request[IO], Response[IO]], ): IO[(User, Option[Authorization])] = signUpAndLogIn(userSignUp.copy(role = Role.Admin), userEndpoint) def signUpAndLogInAsCustomer( userSignUp: SignupRequest, userEndpoint: Kleisli[IO, Request[IO], Response[IO]], ): IO[(User, Option[Authorization])] = signUpAndLogIn(userSignUp.copy(role = Role.Customer), userEndpoint) }
Example 8
Source File: JwtTokenAuthMiddleware.scala From core with Apache License 2.0 | 5 votes |
package com.smartbackpackerapp.http.auth import cats.data.{EitherT, Kleisli, OptionT} import cats.effect.Sync import cats.syntax.applicativeError._ import cats.syntax.functor._ import com.smartbackpackerapp.http.auth.JwtTokenAuthMiddleware.AuthConfig import org.http4s.Credentials.Token import org.http4s.dsl.Http4sDsl import org.http4s.{AuthScheme, AuthedService, Request} import org.http4s.headers.Authorization import org.http4s.server.AuthMiddleware import tsec.jws.mac.JWTMac import tsec.mac.imports._ object JwtTokenAuthMiddleware { def apply[F[_] : Sync](apiToken: Option[String]): F[AuthMiddleware[F, String]] = new Middleware[F](apiToken).middleware case class AuthConfig(jwtKey: MacSigningKey[HMACSHA256]) } class Middleware[F[_]](apiToken: Option[String])(implicit F: Sync[F]) { private val ifEmpty = F.raiseError[AuthMiddleware[F, String]](new Exception("Api Token not found")) private def generateJwtKey(token: String): F[MacSigningKey[HMACSHA256]] = { F.catchNonFatal(HMACSHA256.buildKeyUnsafe(token.getBytes)) } val middleware: F[AuthMiddleware[F, String]] = apiToken.fold(ifEmpty) { token => generateJwtKey(token).map { jwtKey => val config = AuthConfig(jwtKey) new JwtTokenAuthMiddleware[F](config).middleware } } } class JwtTokenAuthMiddleware[F[_] : Sync](config: AuthConfig) extends Http4sDsl[F] { private val onFailure: AuthedService[String, F] = Kleisli(req => OptionT.liftF(Forbidden(req.authInfo))) private def bearerTokenFromRequest(request: Request[F]): OptionT[F, String] = OptionT.fromOption[F] { request.headers.get(Authorization).collect { case Authorization(Token(AuthScheme.Bearer, token)) => token } } private def verifyToken(request: Request[F], jwtKey: MacSigningKey[HMACSHA256]): OptionT[F, String] = for { token <- bearerTokenFromRequest(request) verified <- OptionT.liftF(JWTMac.verifyAndParse[F, HMACSHA256](token, jwtKey)) accessToken <- OptionT.fromOption[F](verified.body.subject) } yield accessToken private def authUser(jwtKey: MacSigningKey[HMACSHA256]): Kleisli[F, Request[F], Either[String, String]] = Kleisli { request => verifyToken(request, jwtKey).value.map { option => Either.cond[String, String](option.isDefined, option.get, "Unable to authorize token") }.recoverWith { case MacVerificationError(msg) => EitherT.leftT(msg).value } } def middleware: AuthMiddleware[F, String] = AuthMiddleware(authUser(config.jwtKey), onFailure) }