Skip to content
http4s middleware for HTTP SPNEGO Authentication
Scala Dockerfile Shell
Branch: master
Clone or download
novakov-alexey Merge pull request #9 from scala-steward/update/http4s-core-0.21.0-M5
Update http4s-blaze-server, http4s-core, ... to 0.21.0-M5
Latest commit acefc7d Sep 21, 2019
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
http4s-spnego/src use java hashmap directly Sep 20, 2019
project
test-server add apply functions as nicer way to create instances, use kind-projec… Sep 18, 2019
.gitignore ignore metals and bloop dirs Sep 20, 2019
.scalafmt.conf init Aug 22, 2019
.travis.yml build both version on CI Sep 3, 2019
README.md update readme Sep 20, 2019
build-testserver.sh codacy issues cleanup Sep 3, 2019
build.sbt add sbt-sonatype plugin Sep 20, 2019
release.sh handle one more case Sep 3, 2019
version.sbt Setting version to 0.2.1-SNAPSHOT Sep 20, 2019

README.md

http4s-spnego

Codacy Badge Maven Central Build Status

This library provides SPNEGO Authentication as a middleware for http4s.

Project is an adaptation of akka-http-spnego, but for http4s.

How to use

  1. Add library into your dependencies:
libraryDependencies += "io.github.novakov-alexey" % "http4s-spnego_2.13" % "<version>"
or 
libraryDependencies += "io.github.novakov-alexey" % "http4s-spnego_2.12" % "<version>"
  1. Instantiate Spnego using SpnegoConfig case class:
val realm = "EXAMPLE.ORG"
val principal = s"HTTP/myservice@$realm"
val keytab = "/etc/krb5.keytab"
val debug = true
val domain = Some("myservice")
val path: Option[String] = None
val tokenValidity: FiniteDuration = 3600.seconds
val cookieName = "http4s.spnego"

val cfg = SpnegoConfig(principal, realm, keytab, debug, None, "secret", domain, path, tokenValidity, cookieName)
val spnego = Spnego[IO](cfg)
  1. Wrap AuthedRoutes with spnego#middleware, so that you can get an instance of SPNEGO token. Wrapped routes will be called successfully only if SPNEGO authentication succeeded.
import cats.effect.Sync
import cats.implicits._
import org.http4s.{AuthedRoutes, HttpRoutes}
import org.http4s.dsl.Http4sDsl

class LoginEndpoint[F[_]: Sync](spnego: Spnego[F]) extends Http4sDsl[F] {

  val routes: HttpRoutes[F] =
    spnego(AuthedRoutes.of[Token, F] {
      case GET -> Root as token =>
        Ok(s"This page is protected using HTTP SPNEGO authentication; logged in as $token")
          .map(_.addCookie(spnego.signCookie(token)))
    })
}
  1. Use routes in your server:
val login = new LoginEndpoint[IO](spnego)
val finalHttpApp = Logger.httpApp(logHeaders = true, logBody = true)(login)

BlazeServerBuilder[F]
  .bindHttp(8080, "0.0.0.0")
  .withHttpApp(finalHttpApp)
  .serve

See tests and test-server module for more examples.

Testing with test server

  1. Make sure Kerberos is installed and configured for your server and client machines.
  2. Configure test server with proper realm, principal, keytab path (see config above)
  3. Authenticate client via kinit CLI tool to the same realm used for the server side
  4. Start test server: sbt 'project test-server' run
  5. Use curl or Web-Browser to initiate a negotiation request (google for that or try this link). In case you want to test with curl, there is command for that:
curl -k --negotiate -u : -b ~/cookiejar.txt -c ~/cookiejar.txt http://<yourserver>:8080/
You can’t perform that action at this time.