Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

To secure a Play application with SAML using pac4j, configure the application as a SAML service provider (SP), connect it to an identity provider (IdP), register the SP metadata with that IdP, and route the IdP’s response to pac4j’s callback. Then configure a pac4j session store and protect the application actions that require authentication. The example below follows the official Java integration for Play 3.0; its dependency versions and settings are not universal across Play releases.

How the Play and SAML login flow fits together

play-pac4j connects pac4j to Play, while pac4j-saml provides the SAML 2 client. Your Play application is the SP; an IdP authenticates the user and returns a SAML response to the SP’s Assertion Consumer Service (ACS), typically the application’s callback endpoint. In the documented flow, an unauthenticated request to a protected action starts authentication at the IdP. After the callback processes the response, pac4j makes the SAML profile available and returns the user to the originally requested URL. See the pac4j SAML client documentation and play-pac4j project documentation.

Check the Play and pac4j versions first

The official Play 3.0 Java example specifies Java 17 or later, Play 3.0, Scala 2.13 or Scala 3, play-pac4j 13.0.3-PLAY3.0, and pac4j-saml 6.5.8. These are example values for that Play integration line, not a general compatibility guarantee. The guide points Play 2.9 and 2.8 users to their corresponding -PLAY2.9 and -PLAY2.8 artifact lines. Check the compatibility information and align all dependencies with your application before copying versions. In sbt, %% selects an artifact for the project’s Scala version. The sample also adds Guice and Caffeine. See the versioned pac4j SAML reference for details relevant to the documented pac4j version.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Example sbt dependencies for Play 3.0

"org.pac4j" %% "play-pac4j" % "13.0.3-PLAY3.0"
"org.pac4j" % "pac4j-saml" % "6.5.8"

Use the exact artifact notation and compatible versions from the guide for your project’s Scala and Play versions. Keep required transitive dependencies, and review exclusions already defined in your build.

Configure the SP, callback, and session store

The following sequence follows the Play 3.0 Java guide. Replace illustrative values with your deployment’s actual URLs, keys, entity identifiers, and IdP metadata. The guide’s complete example and route setup are in the pac4j Play SAML guide.

  1. Generate an SP keystore

    The sample uses Java keytool to create an RSA key pair in a JKS file under Play’s conf directory. Its example uses a 2048-bit RSA key and a validity of 3650 days; these are sample configuration values, not a universal requirement. The SP uses its key pair to sign requests and decrypt assertions. Replace the sample alias and passwords, and protect the keystore and its secrets in deployment.

  2. Set the SAML configuration

    Configure SAML2Configuration with the keystore path and passwords, the IdP metadata location, the SP entity ID, and an output path for SP metadata. The guide’s demo uses test IdP metadata; use the metadata source and registration details supplied for your actual IdP. The entity ID and callback/ACS address must match the values registered at the IdP.

    Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  3. Create and reuse the SAML client

    Create one SAML2Client from the configuration and provide it through pac4j’s Config. The example sets the callback base URL with new Config(baseUrl + "/callback", saml2Client); pac4j appends the client-name parameter. Reuse the same client instance so its replay-cache state persists between authentications, unless you provide a suitable custom replay-cache provider.

  4. Install a Play session store

    pac4j needs a session store for state and profile handling in this integration. The sample binds PlayCacheSessionStore using Play’s cache and installs it with config.setSessionStoreFactory. Play’s session cookie alone is not a server-side session store for pac4j state. The guide also describes PlayCookieSessionStore, which stores encrypted state in the cookie without a cache; it does not establish a general operational winner between the two.

  5. Bind callback and logout controllers

    Bind pac4j’s CallbackController and LogoutController, then set the callback and logout destinations and session behavior for your application. The example defines both GET and POST callback routes. SAML responses are commonly delivered through a cross-origin POST, so the POST callback route in Play needs the + nocsrf modifier; otherwise, Play’s CSRF filter may reject the IdP’s response.

  6. Register the SP with the IdP

    When the client initializes, the sample writes SP metadata to the configured output path. Register that metadata with the IdP, or provide the corresponding SP entity ID and ACS URL through the IdP’s registration process. Ensure the IdP sends its response to the callback address configured in pac4j. An incorrect entity ID or missing SP registration can produce an unknown-service-provider error.

    Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Protect Play actions or URL patterns

Choose the protection method that matches how your application organizes routes. The guide presents action-level annotations and URL-pattern filtering as alternatives.

Approach How it is applied Useful when
Action-level @Secure Add @Secure(clients = "SAML2Client") to a Java action. You want to declare protection on individual actions.
URL-pattern SecurityFilter Configure pac4j’s SecurityFilter to protect matching URL patterns; authorizers can add role checks. You want to apply security rules to route patterns.

Once the callback succeeds, the example restores the originally requested URL. Scala applications can use the Scala demo and library documentation linked from the play-pac4j project for the corresponding integration.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Understand local logout, SAML SLO, and user attributes

Local logout is not single logout

A basic /logout route removes the local login. It does not by itself sign the user out of the IdP or other applications. SAML single logout (SLO) is a separate flow: it requires a central logout controller configured for local and central logout, IdP metadata declaring a SingleLogoutService, and a request signature and binding compatible with the IdP’s expectations.

Attribute availability depends on the IdP

The SAML profile exposes attributes returned by the IdP. pac4j can map raw attribute identifiers to more readable names, but mapping cannot supply an attribute the IdP did not release. If a value is missing, check both the attribute mapping in the application and the IdP’s release policy for this SP.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Troubleshoot common integration failures

  • Startup says no session store is configured: configure and install a pac4j-compatible Play session store.
  • The IdP reports an unknown SP or service provider: verify that the SP metadata or entity ID is registered and that the IdP’s entity ID matches the configured value.
  • The callback returns HTTP 403: check that the POST callback route has Play’s + nocsrf modifier.
  • Authentication-age validation fails: check clock synchronization and the configured authentication lifetime. In the documented pac4j 6.5.8 sample, a maximum authentication lifetime of zero disables that age check; assertion validity timestamps are still checked. This example-specific setting does not disable all SAML validity checks.
  • The callback does not complete successfully: compare the callback URL in pac4j with the IdP’s registered ACS address, then verify the SP entity ID, metadata, keys, and IdP metadata source.

For release-specific configuration, consult the pac4j SAML documentation alongside the Play integration guide; framework versions, dependency compatibility, and IdP configuration can change.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.