I have this tapir endpoint:
val secretPlace: Endpoint[AuthenticationToken, Unit, String, String, Any] =
endpoint.get
.securityIn("secret-place")
.securityIn(auth.bearer[String]().mapTo[AuthenticationToken])
.out(stringBody)
.errorOut(stringBody)
and security logic and server logic:
Http4sServerInterpreterIO .toRoutes(
secretPlace
.serverSecurityLogic(token => IO(checkToken(token)))
.serverLogic(authDetails => _ => IO(("Your details: " + authDetails).asRight[String]))
)
but the token I received is a string of : {{token}}
No matter if there is the Authorizarion header set or not.
adamw
August 5, 2024, 10:26am
2
Can you share a reproducible example? The following seems to work fine:
//> using dep com.softwaremill.sttp.tapir::tapir-core:1.11.0
//> using dep com.softwaremill.sttp.tapir::tapir-http4s-server:1.11.0
//> using dep com.softwaremill.sttp.client3::core:3.9.7
//> using dep org.http4s::http4s-blaze-server:0.23.16
package sttp.tapir.examples
import cats.effect.*
import cats.syntax.all.*
import org.http4s.HttpRoutes
import org.http4s.blaze.server.BlazeServerBuilder
import org.http4s.server.Router
import sttp.tapir.*
import sttp.tapir.server.http4s.Http4sServerInterpreter
import scala.concurrent.ExecutionContext
object HelloWorldHttp4sServer extends IOApp:
case class AuthenticationToken(value: String)
val secretPlace: Endpoint[AuthenticationToken, Unit, String, String, Any] =
endpoint.get
.securityIn("secret-place")
.securityIn(auth.bearer[String]().mapTo[AuthenticationToken])
.out(stringBody)
.errorOut(stringBody)
def checkToken(token: AuthenticationToken): Either[String, String] =
println("GOT TOKEN: " + token)
Right("ok")
val r = Http4sServerInterpreter[IO]().toRoutes(
secretPlace
.serverSecurityLogic(token => IO(checkToken(token)))
.serverLogic(authDetails => _ => IO(("Your details: " + authDetails).asRight[String]))
)
implicit val ec: ExecutionContext = scala.concurrent.ExecutionContext.Implicits.global
override def run(args: List[String]): IO[ExitCode] =
// starting the server
BlazeServerBuilder[IO]
.withExecutionContext(ec)
.bindHttp(8080, "localhost")
.withHttpApp(Router("/" -> r).orNotFound)
.resource
.use { _ => IO.never }
.as(ExitCode.Success)
Test:
% curl -H "Authorization: Bearer mytoken123" "http://localhost:8080/secret-place"
Your details: ok%
In the server logs:
GOT TOKEN: AuthenticationToken(mytoken123)
Why are you using the following dependency?
using dep com.softwaremill.sttp.client3::core:3.9.7
It’s fixed, I was using Bruno to execute Rest requests and it didn’t send the Authorization header. I checked with CURL and it works. Thanks for the reply @adamw !
adamw
August 5, 2024, 11:57am
6
Ah that’s a left-over from another example.
Anyway, good to hear it works