works.iterative.server.http.impl.pac4j

Members list

Type members

Classlikes

class ConstantTimeCsrfAuthorizer extends CsrfAuthorizer

Replaces pac4j-core's CsrfAuthorizer.hashEquals with a UTF-8 byte comparison via java.security.MessageDigest.isEqual.

Replaces pac4j-core's CsrfAuthorizer.hashEquals with a UTF-8 byte comparison via java.security.MessageDigest.isEqual.

Rationale — pac4j-core 6.3.2 CsrfAuthorizer.hashEquals(a, b) returns a.hashCode() == b.hashCode(). String.hashCode() is a 32-bit int, so any attacker that can enumerate strings offline can find one with the same hash as the target token (birthday-collision ≈ 2^16 tries; targeted-collision ≈ 2^32 — both trivial modern-hardware budgets). The comparison also is not constant-time: String.hashCode() iterates over the string and short-circuits, leaking length information via timing. MessageDigest.isEqual compares the full byte arrays in constant time, closing both issues.

Register this authorizer under the standard csrfCheck name in the Pac4j Config (see Pac4jCsrfSupport.installConstantTimeCsrfAuthorizer). DefaultAuthorizationChecker consults config.getAuthorizers before falling back to pac4j-core's stock singleton, so naming this subclass csrfCheck replaces the vulnerable comparator in the default authorizer chain that Pac4jHttpSecurity.secure applies to IndirectClient sessions.

See docs/CSRF_GUIDE.md for the full picture of Pac4j session-managed CSRF wiring.

Attributes

Supertypes
class CsrfAuthorizer
trait Authorizer
class Object
trait Matchable
class Any
trait HttpSecurity

Attributes

Supertypes
class Object
trait Matchable
class Any
Known subtypes
case class OidcClientConfig(clientId: String, clientSecret: String, discoveryURI: String, audience: Option[String] = ...)

Attributes

Supertypes
trait Serializable
trait Product
trait Equals
class Object
trait Matchable
class Any
Show all
object Pac4jAuthenticationAdapter extends AuthenticationService

Adapter that bridges Pac4J authentication to ZIO AuthenticationService.

Adapter that bridges Pac4J authentication to ZIO AuthenticationService.

This adapter:

  • Maps Pac4J CommonProfile (Java) to BasicProfile (Scala/ZIO)
  • Handles null values defensively with Option
  • Stores user context in FiberRef for request-scoped authentication
  • Extracts roles from Pac4J profile attributes

Example usage:

// After Pac4J successful authentication with CommonProfile
val profile: CommonProfile = ... // from Pac4J
val token = AccessToken("oauth-token-123")

for
 adapter <- ZIO.service[AuthenticationService]
 basicProfile = Pac4jAuthenticationAdapter.mapProfile(profile)
 _ <- adapter.loggedIn(token, basicProfile)
 currentUser <- adapter.currentUserInfo
yield currentUser // Some(AuthedUserInfo(...))

Attributes

Supertypes
trait AuthenticationService
class Object
trait Matchable
class Any
Self type
class Pac4jConfigFactory[F <: ([_] =>> AnyRef)](baseUri: BaseUri, pac4jConfig: Pac4jSecurityConfig, dispatcher: Dispatcher[F], authorizationGenerator: AuthorizationGenerator = ...)(implicit evidence$1: Sync[F]) extends ConfigFactory

Attributes

Companion
object
Supertypes
trait ConfigFactory
class Object
trait Matchable
class Any

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type
trait Pac4jCsrfSupport[F[_]]

Reads Pac4j's session-managed CSRF token so a downstream handler can render it into a page (typically a <meta name="csrf-token"> tag consumed by HTMX or a form's hidden field).

Reads Pac4j's session-managed CSRF token so a downstream handler can render it into a page (typically a <meta name="csrf-token"> tag consumed by HTMX or a form's hidden field).

Pac4j's DefaultMatchingChecker automatically wires CsrfTokenGeneratorMatcher into the matcher chain when the session has an active IndirectClient. That matcher stores the per-session token under Pac4jConstants.CSRF_TOKEN in the session. Handlers cannot easily retrieve it from the request because Http4sWebContext writes the token under a per-instance vault Key — so this implementation reads the shared SessionStore directly with a fresh WebContext built from the incoming request.

See docs/CSRF_GUIDE.md for the end-to-end wiring recipe.

Attributes

Companion
object
Supertypes
class Object
trait Matchable
class Any

Attributes

Companion
trait
Supertypes
class Object
trait Matchable
class Any
Self type
class Pac4jHttpSecurity[F <: ([_] =>> AnyRef)](baseUri: BaseUri, config: Pac4jSecurityConfig, pac4jConfig: Config, dispatcher: Dispatcher[F])(implicit evidence$1: Sync[F]) extends HttpSecurity

Attributes

Supertypes
trait HttpSecurity
class Object
trait Matchable
class Any
trait Pac4jModuleRegistry[R, U] extends ModuleRegistry[R]

Attributes

Supertypes
trait ModuleRegistry[R]
class Object
trait Matchable
class Any
case class Pac4jSecurityConfig(urlBase: String, callbackBase: String, defaultUrl: Option[String], logoutUrl: Option[String], logoutUrlPattern: Option[String], sessionSecret: String, client: OidcClientConfig, clients: Map[String, OidcClientConfig])

Attributes

Companion
object
Supertypes
trait Serializable
trait Product
trait Equals
class Object
trait Matchable
class Any
Show all

Attributes

Companion
class
Supertypes
trait Product
trait Mirror
class Object
trait Matchable
class Any
Self type