{"componentChunkName":"component---src-templates-tag-js","path":"/tags/pac-4-j/","result":{"data":{"site":{"siteMetadata":{"title":"LoginRadius Blog"}},"allMarkdownRemark":{"totalCount":1,"edges":[{"node":{"fields":{"slug":"/engineering/guest-post/add-authentication-to-play-framework-with-oidc-and-loginradius/"},"html":"<p>In this blog post, I will write a step-by-step tutorial to add Authentication to the Play Framework Application with OIDC and LoginRadius. I will be using <a href=\"http://www.pac4j.org/\">pac4j</a> and it's <a href=\"https://github.com/pac4j/play-pac4j\">play-pac4j</a> integration in this tutorial. Before jumping into the tutorial, let's learn about few concepts. </p>\n<h2 id=\"what-is-openid-connect-oidc-protocol\" style=\"position:relative;\"><a href=\"#what-is-openid-connect-oidc-protocol\" aria-label=\"what is openid connect oidc protocol permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What is OpenID Connect (OIDC) Protocol?</h2>\n<p>OIDC is an authentication protocol that allows users to verify their identity when they are trying to access a protected HTTPS endpoint. OIDC is an evolutionary development of ideas implemented earlier in OAuth and OpenID.</p>\n<p>OpenID Connect allows clients to request and receive information about authenticated sessions and end-users. It allows all types of clients, including </p>\n<ul>\n<li>Web-based</li>\n<li>Mobile</li>\n<li>Javascript clients etc...</li>\n</ul>\n<p>You can find out more details about <a href=\"https://openid.net/connect/\">OIDC here</a></p>\n<h2 id=\"what-is-play-framework\" style=\"position:relative;\"><a href=\"#what-is-play-framework\" aria-label=\"what is play framework permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What is Play Framework?</h2>\n<p>Play Framework is an open-source web application framework that follows the model–view–controller architectural pattern. It is written in Scala and usable from other programming languages that are compiled to JVM Bytecode.</p>\n<p>It makes it easy to build web applications with Java &#x26; Scala. Play is based on a lightweight, stateless, web-friendly architecture. Built on Akka, Play provides predictable and minimal resource consumption (CPU, memory, threads) for highly-scalable applications.</p>\n<h2 id=\"what-is-pac4j\" style=\"position:relative;\"><a href=\"#what-is-pac4j\" aria-label=\"what is pac4j permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What is pac4j?</h2>\n<p><a href=\"http://www.pac4j.org/\">pac4j</a> is an easy and powerful security engine for Java to authenticate users, get their profiles and manage authorizations in order to secure web applications and web services.</p>\n<p>It provides a comprehensive set of concepts and components. It is based on Java and available under the Apache 2 license. It is available for most frameworks/tools and supports most authentication/authorization mechanisms.</p>\n<p>pac4j is supported with most of the Java frameworks like</p>\n<ul>\n<li>Spring Web MVC </li>\n<li>Spring Boot </li>\n<li>Spring Security (Spring Boot) </li>\n<li>Play 2.x </li>\n<li>Vertx Spark Java </li>\n<li>Javalin  </li>\n<li>Dropwizard </li>\n<li>Lagom </li>\n<li>Akka HTTP &#x26; many more...</li>\n</ul>\n<h2 id=\"getting-started\" style=\"position:relative;\"><a href=\"#getting-started\" aria-label=\"getting started permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Getting started</h2>\n<p>There are multiple options you can get started with the Play framework. </p>\n<ul>\n<li>You can create a new Play project by downloading the <a href=\"https://playframework.com/download#starters\">starter project here</a></li>\n<li>Create a new Play application using <code>sbt</code>.</li>\n</ul>\n<p>For this tutorial, I will be using creating a new play project using <code>sbt</code>.</p>\n<h3 id=\"install-sbt-on-mac-os\" style=\"position:relative;\"><a href=\"#install-sbt-on-mac-os\" aria-label=\"install sbt on mac os permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Install sbt on Mac OS</h3>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"console\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">brew install sbt</span></code></pre>\n<p>You can find <a href=\"https://www.scala-sbt.org/release/docs/Setup.html\">Installation steps for Windows and Linux</a> here.</p>\n<h3 id=\"prerequisites\" style=\"position:relative;\"><a href=\"#prerequisites\" aria-label=\"prerequisites permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Prerequisites</h3>\n<p>For this tutorial, I will be using </p>\n<ul>\n<li>Java 11</li>\n<li>sbt - 1.5.3</li>\n<li>play-pac4j - 11.0.0-PLAY2.8</li>\n<li>pac4j-oidc - 5.1.0</li>\n</ul>\n<h2 id=\"create-new-play-project\" style=\"position:relative;\"><a href=\"#create-new-play-project\" aria-label=\"create new play project permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Create New Play Project</h2>\n<p>Create a new java play project using the following command</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"console\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">sbt new playframework/play-java-seed.g8</span></code></pre>\n<p>The above command will prompt you to fill in the project <code>name</code> and project package structure in <code>organization</code> as shown below.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"console\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">[info] welcome to sbt 1.5.3 (Oracle Corporation Java 11.0.2)</span>\n<span class=\"grvsc-line\">[info] set current project to new (in build file:/private/var/folders/_9/rcqwq2vx1cl_1sc4xdhb5_5c0000gn/T/sbt_661d1bf7/new/)</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">This template generates a Play Java project</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">name [play-java-seed]: loginradius-play-oidc</span>\n<span class=\"grvsc-line\">organization [com.example]: com.loginradius.developer</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">Template applied in /Users/vishnuchilamakuru/self/longinradius/./loginradius-play-oidc</span></code></pre>\n<h2 id=\"run-play-project\" style=\"position:relative;\"><a href=\"#run-play-project\" aria-label=\"run play project permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Run Play Project</h2>\n<p>Now that the project is created with a base template. You can test it by running the project using the following command from <code>loginradius-play-oidc</code> folder.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"console\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">sbt run</span></code></pre>\n<p>Now visit <code>http://localhost:9000</code>, and it should look like this.</p>\n<p><img src=\"/9cfca8fc8971d0535c27bba8d3c3734f/play-project-homepage.webp\" alt=\"play-project-homepage.webp\"></p>\n<h2 id=\"integrate-pac4j-with-play-project\" style=\"position:relative;\"><a href=\"#integrate-pac4j-with-play-project\" aria-label=\"integrate pac4j with play project permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Integrate pac4j with Play Project</h2>\n<h3 id=\"1-add-pac4j-dependencies-to-buildsbt\" style=\"position:relative;\"><a href=\"#1-add-pac4j-dependencies-to-buildsbt\" aria-label=\"1 add pac4j dependencies to buildsbt permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>1. Add pac4j dependencies to <code>build.sbt</code></h3>\n<p>Add pac4j dependencies, Java 11 as required, and target version to compile the project in <code>build.sbt</code>.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"scala\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">name := &quot;&quot;&quot;loginradius-play-oidc&quot;&quot;&quot;</span>\n<span class=\"grvsc-line\">organization := &quot;com.loginradius.developer&quot;</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">version := &quot;1.0-SNAPSHOT&quot;</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">lazy val root = (project in file(&quot;.&quot;)).enablePlugins(PlayJava)</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">scalaVersion := &quot;2.13.6&quot;</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">initialize := {</span>\n<span class=\"grvsc-line\">  val _ = initialize.value // run the previous initialization</span>\n<span class=\"grvsc-line\">  val required = &quot;11&quot;</span>\n<span class=\"grvsc-line\">  val current  = sys.props(&quot;java.specification.version&quot;)</span>\n<span class=\"grvsc-line\">  assert(current == required, s&quot;Unsupported JDK: java.specification.version $current != $required&quot;)</span>\n<span class=\"grvsc-line\">}</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">scalacOptions += &quot;-target:jvm-11&quot;</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">javacOptions ++= Seq(&quot;-source&quot;, &quot;11&quot;, &quot;-target&quot;, &quot;11&quot;)</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">libraryDependencies ++= Seq(</span>\n<span class=\"grvsc-line\">  guice,</span>\n<span class=\"grvsc-line\">  ehcache,</span>\n<span class=\"grvsc-line\">  &quot;org.pac4j&quot; %% &quot;play-pac4j&quot; % &quot;11.0.0-PLAY2.8&quot;,</span>\n<span class=\"grvsc-line\">  &quot;org.pac4j&quot; % &quot;pac4j-oidc&quot; % &quot;5.1.0&quot;,</span>\n<span class=\"grvsc-line\">  &quot;com.typesafe.play&quot; % &quot;play-cache_2.13&quot; % &quot;2.8.8&quot;,</span>\n<span class=\"grvsc-line\">  &quot;com.fasterxml.jackson.module&quot; %% &quot;jackson-module-scala&quot; % &quot;2.12.3&quot;</span>\n<span class=\"grvsc-line\">)</span></code></pre>\n<h3 id=\"2-create-security-module\" style=\"position:relative;\"><a href=\"#2-create-security-module\" aria-label=\"2 create security module permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>2. Create Security Module</h3>\n<p>Create <code>app/modules/SecurityModule.java</code>. This class configures OIDC, sets up a secure HttpActionAdapter, and registers callback and logout controllers.</p>\n<ul>\n<li>SecurityModule.java</li>\n</ul>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"java\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">package</span><span class=\"mtk1\"> modules;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> com.google.inject.AbstractModule;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> com.nimbusds.oauth2.sdk.ParseException;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> com.nimbusds.oauth2.sdk.auth.ClientAuthenticationMethod;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> com.nimbusds.openid.connect.sdk.op.OIDCProviderMetadata;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> com.typesafe.config.Config;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> net.minidev.json.JSONObject;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> org.pac4j.core.authorization.authorizer.RequireAnyRoleAuthorizer;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> org.pac4j.core.client.Clients;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> org.pac4j.core.context.session.SessionStore;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> org.pac4j.oidc.client.OidcClient;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> org.pac4j.oidc.config.OidcConfiguration;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> org.pac4j.play.CallbackController;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> org.pac4j.play.LogoutController;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> org.pac4j.play.http.PlayHttpActionAdapter;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> org.pac4j.play.store.PlayCacheSessionStore;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> play.Environment;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> java.util.Optional;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">public</span><span class=\"mtk1\"> </span><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">SecurityModule</span><span class=\"mtk1\"> </span><span class=\"mtk4\">extends</span><span class=\"mtk1\"> </span><span class=\"mtk10\">AbstractModule</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">private</span><span class=\"mtk1\"> </span><span class=\"mtk4\">final</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Config</span><span class=\"mtk1\"> </span><span class=\"mtk12\">configuration</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">public</span><span class=\"mtk1\"> </span><span class=\"mtk11\">SecurityModule</span><span class=\"mtk1\">(</span><span class=\"mtk4\">final</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Environment</span><span class=\"mtk1\"> </span><span class=\"mtk12\">environment</span><span class=\"mtk1\">, </span><span class=\"mtk4\">final</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Config</span><span class=\"mtk1\"> </span><span class=\"mtk12\">configuration</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">configuration</span><span class=\"mtk1\"> = configuration;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    @</span><span class=\"mtk10\">Override</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">protected</span><span class=\"mtk1\"> </span><span class=\"mtk10\">void</span><span class=\"mtk1\"> </span><span class=\"mtk11\">configure</span><span class=\"mtk1\">() {</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk11\">bind</span><span class=\"mtk1\">(</span><span class=\"mtk12\">SessionStore</span><span class=\"mtk1\">.</span><span class=\"mtk12\">class</span><span class=\"mtk1\">).</span><span class=\"mtk11\">to</span><span class=\"mtk1\">(</span><span class=\"mtk12\">PlayCacheSessionStore</span><span class=\"mtk1\">.</span><span class=\"mtk12\">class</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">final</span><span class=\"mtk1\"> </span><span class=\"mtk10\">OidcConfiguration</span><span class=\"mtk1\"> </span><span class=\"mtk12\">oidcConfiguration</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">new</span><span class=\"mtk1\"> </span><span class=\"mtk11\">OidcConfiguration</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">oidcConfiguration</span><span class=\"mtk1\">.</span><span class=\"mtk11\">setDiscoveryURI</span><span class=\"mtk1\">(</span><span class=\"mtk12\">configuration</span><span class=\"mtk1\">.</span><span class=\"mtk11\">getString</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;oidc.discoveryUri&quot;</span><span class=\"mtk1\">));</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">oidcConfiguration</span><span class=\"mtk1\">.</span><span class=\"mtk11\">setClientId</span><span class=\"mtk1\">(</span><span class=\"mtk12\">configuration</span><span class=\"mtk1\">.</span><span class=\"mtk11\">getString</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;oidc.clientId&quot;</span><span class=\"mtk1\">));</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">oidcConfiguration</span><span class=\"mtk1\">.</span><span class=\"mtk11\">setSecret</span><span class=\"mtk1\">(</span><span class=\"mtk12\">configuration</span><span class=\"mtk1\">.</span><span class=\"mtk11\">getString</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;oidc.clientSecret&quot;</span><span class=\"mtk1\">));</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">oidcConfiguration</span><span class=\"mtk1\">.</span><span class=\"mtk11\">setClientAuthenticationMethod</span><span class=\"mtk1\">(</span><span class=\"mtk12\">ClientAuthenticationMethod</span><span class=\"mtk1\">.</span><span class=\"mtk12\">CLIENT_SECRET_BASIC</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk11\">addProviderMetadata</span><span class=\"mtk1\">(oidcConfiguration);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">final</span><span class=\"mtk1\"> </span><span class=\"mtk10\">OidcClient</span><span class=\"mtk1\"> </span><span class=\"mtk12\">oidcClient</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">new</span><span class=\"mtk1\"> </span><span class=\"mtk11\">OidcClient</span><span class=\"mtk1\">(oidcConfiguration);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">oidcClient</span><span class=\"mtk1\">.</span><span class=\"mtk11\">addAuthorizationGenerator</span><span class=\"mtk1\">((ctx, session, profile) </span><span class=\"mtk4\">-&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">profile</span><span class=\"mtk1\">.</span><span class=\"mtk11\">addRole</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;ROLE_ADMIN&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Optional</span><span class=\"mtk1\">.</span><span class=\"mtk11\">of</span><span class=\"mtk1\">(profile);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        });</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">final</span><span class=\"mtk1\"> </span><span class=\"mtk10\">String</span><span class=\"mtk1\"> </span><span class=\"mtk12\">baseUrl</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">configuration</span><span class=\"mtk1\">.</span><span class=\"mtk11\">getString</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;baseUrl&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">final</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Clients</span><span class=\"mtk1\"> </span><span class=\"mtk12\">clients</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">new</span><span class=\"mtk1\"> </span><span class=\"mtk11\">Clients</span><span class=\"mtk1\">(baseUrl + </span><span class=\"mtk8\">&quot;/callback&quot;</span><span class=\"mtk1\">,  oidcClient);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">final</span><span class=\"mtk1\"> </span><span class=\"mtk10\">org</span><span class=\"mtk1\">.</span><span class=\"mtk10\">pac4j</span><span class=\"mtk1\">.</span><span class=\"mtk10\">core</span><span class=\"mtk1\">.</span><span class=\"mtk10\">config</span><span class=\"mtk1\">.</span><span class=\"mtk10\">Config</span><span class=\"mtk1\"> </span><span class=\"mtk12\">config</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">new</span><span class=\"mtk1\"> org.pac4j.core.config.</span><span class=\"mtk11\">Config</span><span class=\"mtk1\">(clients);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">config</span><span class=\"mtk1\">.</span><span class=\"mtk11\">addAuthorizer</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;admin&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk15\">new</span><span class=\"mtk1\"> </span><span class=\"mtk11\">RequireAnyRoleAuthorizer</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;ROLE_ADMIN&quot;</span><span class=\"mtk1\">));</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">config</span><span class=\"mtk1\">.</span><span class=\"mtk11\">setHttpActionAdapter</span><span class=\"mtk1\">(</span><span class=\"mtk12\">PlayHttpActionAdapter</span><span class=\"mtk1\">.</span><span class=\"mtk12\">INSTANCE</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk11\">bind</span><span class=\"mtk1\">(</span><span class=\"mtk12\">org</span><span class=\"mtk1\">.</span><span class=\"mtk12\">pac4j</span><span class=\"mtk1\">.</span><span class=\"mtk12\">core</span><span class=\"mtk1\">.</span><span class=\"mtk12\">config</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Config</span><span class=\"mtk1\">.</span><span class=\"mtk12\">class</span><span class=\"mtk1\">).</span><span class=\"mtk11\">toInstance</span><span class=\"mtk1\">(config);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk3\">// callback</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">final</span><span class=\"mtk1\"> </span><span class=\"mtk10\">CallbackController</span><span class=\"mtk1\"> </span><span class=\"mtk12\">callbackController</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">new</span><span class=\"mtk1\"> </span><span class=\"mtk11\">CallbackController</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">callbackController</span><span class=\"mtk1\">.</span><span class=\"mtk11\">setDefaultUrl</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk11\">bind</span><span class=\"mtk1\">(</span><span class=\"mtk12\">CallbackController</span><span class=\"mtk1\">.</span><span class=\"mtk12\">class</span><span class=\"mtk1\">).</span><span class=\"mtk11\">toInstance</span><span class=\"mtk1\">(callbackController);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk3\">// logout</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">final</span><span class=\"mtk1\"> </span><span class=\"mtk10\">LogoutController</span><span class=\"mtk1\"> </span><span class=\"mtk12\">logoutController</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">new</span><span class=\"mtk1\"> </span><span class=\"mtk11\">LogoutController</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">logoutController</span><span class=\"mtk1\">.</span><span class=\"mtk11\">setDefaultUrl</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/?defaulturlafterlogout&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk11\">bind</span><span class=\"mtk1\">(</span><span class=\"mtk12\">LogoutController</span><span class=\"mtk1\">.</span><span class=\"mtk12\">class</span><span class=\"mtk1\">).</span><span class=\"mtk11\">toInstance</span><span class=\"mtk1\">(logoutController);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">private</span><span class=\"mtk1\"> </span><span class=\"mtk10\">void</span><span class=\"mtk1\"> </span><span class=\"mtk11\">addProviderMetadata</span><span class=\"mtk1\">(</span><span class=\"mtk10\">OidcConfiguration</span><span class=\"mtk1\"> </span><span class=\"mtk12\">oidcConfiguration</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk10\">JSONObject</span><span class=\"mtk1\"> </span><span class=\"mtk12\">jsonObj</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">new</span><span class=\"mtk1\"> </span><span class=\"mtk11\">JSONObject</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">jsonObj</span><span class=\"mtk1\">.</span><span class=\"mtk11\">appendField</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;token_endpoint&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">configuration</span><span class=\"mtk1\">.</span><span class=\"mtk11\">getString</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;oidc.tokenUri&quot;</span><span class=\"mtk1\">));</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">final</span><span class=\"mtk1\"> </span><span class=\"mtk10\">OIDCProviderMetadata</span><span class=\"mtk1\"> </span><span class=\"mtk12\">providerMetaData</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">try</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            providerMetaData = </span><span class=\"mtk12\">OIDCProviderMetadata</span><span class=\"mtk1\">.</span><span class=\"mtk11\">parse</span><span class=\"mtk1\">(jsonObj);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">oidcConfiguration</span><span class=\"mtk1\">.</span><span class=\"mtk11\">setProviderMetadata</span><span class=\"mtk1\">(providerMetaData);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        } </span><span class=\"mtk15\">catch</span><span class=\"mtk1\"> (</span><span class=\"mtk10\">ParseException</span><span class=\"mtk1\"> </span><span class=\"mtk12\">e</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">e</span><span class=\"mtk1\">.</span><span class=\"mtk11\">printStackTrace</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<h3 id=\"3-create-secured-endpoint-in-controller\" style=\"position:relative;\"><a href=\"#3-create-secured-endpoint-in-controller\" aria-label=\"3 create secured endpoint in controller permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>3. Create Secured Endpoint in Controller</h3>\n<p>In <code>app/controllers/HomeController.java</code> add the following methods</p>\n<ul>\n<li>A method that is secured by the OIDC client</li>\n<li>A method to show the profile information returned from LoginRadius(or any identity provider) on successful login.</li>\n<li>A method to get profile information</li>\n</ul>\n<p>After adding the above methods <code>HomeController.java</code> looks like this.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"java\" data-index=\"6\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">package</span><span class=\"mtk1\"> controllers;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> com.google.inject.Inject;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> org.pac4j.core.context.session.SessionStore;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> org.pac4j.core.profile.ProfileManager;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> org.pac4j.core.profile.UserProfile;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> org.pac4j.play.context.PlayContextFactory;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> org.pac4j.play.java.Secure;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> org.pac4j.play.store.PlayCacheSessionStore;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> play.mvc.*;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> java.util.ArrayList;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> java.util.List;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">/**</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\"> * This controller contains an action to handle HTTP requests</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\"> * to the application&#39;s home page.</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\"> */</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">public</span><span class=\"mtk1\"> </span><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">HomeController</span><span class=\"mtk1\"> </span><span class=\"mtk4\">extends</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Controller</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">    /**</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">     * An action that renders an HTML page with a welcome message.</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">     * The configuration in the &lt;code&gt;routes&lt;/code&gt; file means that</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">     * this method will be called when the application receives a</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">     * &lt;code&gt;GET&lt;/code&gt; request with a path of &lt;code&gt;/&lt;/code&gt;.</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">     */</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">public</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Result</span><span class=\"mtk1\"> </span><span class=\"mtk11\">index</span><span class=\"mtk1\">() {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk11\">ok</span><span class=\"mtk1\">(</span><span class=\"mtk12\">views</span><span class=\"mtk1\">.</span><span class=\"mtk12\">html</span><span class=\"mtk1\">.</span><span class=\"mtk12\">index</span><span class=\"mtk1\">.</span><span class=\"mtk11\">render</span><span class=\"mtk1\">());</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    @</span><span class=\"mtk10\">Secure</span><span class=\"mtk1\">(clients = </span><span class=\"mtk8\">&quot;OidcClient&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">public</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Result</span><span class=\"mtk1\"> </span><span class=\"mtk11\">oidcIndex</span><span class=\"mtk1\">(</span><span class=\"mtk10\">Http</span><span class=\"mtk1\">.</span><span class=\"mtk10\">Request</span><span class=\"mtk1\"> </span><span class=\"mtk12\">req</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk11\">protectedIndex</span><span class=\"mtk1\">(req);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">public</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Result</span><span class=\"mtk1\"> </span><span class=\"mtk11\">protectedIndex</span><span class=\"mtk1\">(</span><span class=\"mtk10\">Http</span><span class=\"mtk1\">.</span><span class=\"mtk10\">Request</span><span class=\"mtk1\"> </span><span class=\"mtk12\">req</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk11\">ok</span><span class=\"mtk1\">(</span><span class=\"mtk12\">views</span><span class=\"mtk1\">.</span><span class=\"mtk12\">html</span><span class=\"mtk1\">.</span><span class=\"mtk12\">protectedindex</span><span class=\"mtk1\">.</span><span class=\"mtk11\">render</span><span class=\"mtk1\">(</span><span class=\"mtk11\">getProfiles</span><span class=\"mtk1\">(req)));</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    @</span><span class=\"mtk10\">Inject</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">private</span><span class=\"mtk1\"> </span><span class=\"mtk10\">SessionStore</span><span class=\"mtk1\"> </span><span class=\"mtk12\">sessionStore</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">private</span><span class=\"mtk1\"> </span><span class=\"mtk10\">List</span><span class=\"mtk1\">&lt;</span><span class=\"mtk10\">UserProfile</span><span class=\"mtk1\">&gt; </span><span class=\"mtk11\">getProfiles</span><span class=\"mtk1\">(</span><span class=\"mtk10\">Http</span><span class=\"mtk1\">.</span><span class=\"mtk10\">Request</span><span class=\"mtk1\"> </span><span class=\"mtk12\">req</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">final</span><span class=\"mtk1\"> </span><span class=\"mtk10\">ProfileManager</span><span class=\"mtk1\"> </span><span class=\"mtk12\">profileManager</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">new</span><span class=\"mtk1\"> </span><span class=\"mtk11\">ProfileManager</span><span class=\"mtk1\">(</span><span class=\"mtk12\">PlayContextFactory</span><span class=\"mtk1\">.</span><span class=\"mtk12\">INSTANCE</span><span class=\"mtk1\">.</span><span class=\"mtk11\">newContext</span><span class=\"mtk1\">(req), sessionStore);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">final</span><span class=\"mtk1\"> </span><span class=\"mtk10\">List</span><span class=\"mtk1\">&lt;</span><span class=\"mtk10\">UserProfile</span><span class=\"mtk1\">&gt; </span><span class=\"mtk12\">profiles</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">ArrayList</span><span class=\"mtk1\">&lt;&gt;();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">profileManager</span><span class=\"mtk1\">.</span><span class=\"mtk11\">getProfile</span><span class=\"mtk1\">().</span><span class=\"mtk11\">isPresent</span><span class=\"mtk1\">()) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">profiles</span><span class=\"mtk1\">.</span><span class=\"mtk11\">add</span><span class=\"mtk1\">(</span><span class=\"mtk12\">profileManager</span><span class=\"mtk1\">.</span><span class=\"mtk11\">getProfile</span><span class=\"mtk1\">().</span><span class=\"mtk11\">get</span><span class=\"mtk1\">());</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> profiles;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<h3 id=\"4-create-views\" style=\"position:relative;\"><a href=\"#4-create-views\" aria-label=\"4 create views permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>4. Create Views</h3>\n<ul>\n<li>Update <code>app/views/index.scala.html</code> as follows to add the link protected by OIDC authentication.</li>\n</ul>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"html\" data-index=\"7\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">@()</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">@</span><span class=\"mtk11\">main</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;Welcome to Play&quot;</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Welcome to Play!</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">a</span><span class=\"mtk1\"> </span><span class=\"mtk12\">href</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;oidc/index.html&quot;</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Protected URL by OIDC</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">a</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<ul>\n<li>Add <code>app/views/protectedindex.scala.html</code> with the following content below. This page will be shown after Successful Login using OIDC in LoginRadius.</li>\n</ul>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"html\" data-index=\"8\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">@(</span><span class=\"mtk12\">profileList</span><span class=\"mtk1\">: </span><span class=\"mtk10\">java</span><span class=\"mtk1\">.</span><span class=\"mtk10\">util</span><span class=\"mtk1\">.</span><span class=\"mtk10\">List</span><span class=\"mtk1\">[</span><span class=\"mtk10\">org</span><span class=\"mtk1\">.</span><span class=\"mtk10\">pac4j</span><span class=\"mtk1\">.</span><span class=\"mtk10\">core</span><span class=\"mtk1\">.</span><span class=\"mtk10\">profile</span><span class=\"mtk1\">.</span><span class=\"mtk10\">UserProfile</span><span class=\"mtk1\">])</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">@import scala.collection.JavaConverters._</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">@profiles() = { @profileList.</span><span class=\"mtk12\">toList</span><span class=\"mtk1\"> }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Protected Area</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">a</span><span class=\"mtk1\"> </span><span class=\"mtk12\">href</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;..&quot;</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Back</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">a</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">ul</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">li</span><span class=\"mtk17\">&gt;&lt;</span><span class=\"mtk4\">a</span><span class=\"mtk1\"> </span><span class=\"mtk12\">href</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;/logout?url=/?forcepostlogouturl&quot;</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Logout</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">a</span><span class=\"mtk17\">&gt;&lt;/</span><span class=\"mtk4\">li</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">ul</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">p</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    profiles: @profiles</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">p</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<h3 id=\"5-configure-routes\" style=\"position:relative;\"><a href=\"#5-configure-routes\" aria-label=\"5 configure routes permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>5. Configure Routes</h3>\n<p>Now we already added methods in <code>HomeController.java</code> and configured callback, logout controllers in <code>SecurityModule.java</code>. Let's configure the routes to map to these methods in <code>conf/routes</code>.</p>\n<ul>\n<li><code>conf/routes</code> will look like this.</li>\n</ul>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"scala\" data-index=\"9\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"># Routes</span>\n<span class=\"grvsc-line\"># This file defines all application routes (Higher priority routes first)</span>\n<span class=\"grvsc-line\"># ~~~~</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"># An example controller showing a sample home page</span>\n<span class=\"grvsc-line\">GET     /                           controllers.HomeController.index</span>\n<span class=\"grvsc-line\">GET     /oidc/index.html            controllers.HomeController.oidcIndex(request: Request)</span>\n<span class=\"grvsc-line\">GET     /protected/index.html       controllers.HomeController.protectedIndex(request: Request)</span>\n<span class=\"grvsc-line\">GET     /callback                   @org.pac4j.play.CallbackController.callback(request: Request)</span>\n<span class=\"grvsc-line\">POST    /callback                   @org.pac4j.play.CallbackController.callback(request: Request)</span>\n<span class=\"grvsc-line\">GET     /logout                     @org.pac4j.play.LogoutController.logout(request: Request)</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"># Map static resources from the /public folder to the /assets URL path</span>\n<span class=\"grvsc-line\">GET     /assets/*file               controllers.Assets.versioned(path=&quot;/public&quot;, file: Asset)</span></code></pre>\n<h3 id=\"6-add-application-configuration-variables\" style=\"position:relative;\"><a href=\"#6-add-application-configuration-variables\" aria-label=\"6 add application configuration variables permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>6. Add Application Configuration variables</h3>\n<p>Finally, configure the variables mentioned in <code>SecurityModule.java</code> in <code>conf/application.conf</code> as follows.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"scala\" data-index=\"10\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">play {</span>\n<span class=\"grvsc-line\">  modules {</span>\n<span class=\"grvsc-line\">    enabled += modules.SecurityModule</span>\n<span class=\"grvsc-line\">  }</span>\n<span class=\"grvsc-line\">}</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">baseUrl = &quot;http://localhost:9000&quot;</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">oidc.discoveryUri = &quot;https://cloud-api.loginradius.com/sso/oidc/v2/{loginradius-site-name}/{loginradius-app-name}/.well-known/openid-configuration&quot;</span>\n<span class=\"grvsc-line\">oidc.clientId = &quot;{clientId}&quot;</span>\n<span class=\"grvsc-line\">oidc.clientSecret = &quot;{clientSecret}&quot;</span>\n<span class=\"grvsc-line\">oidc.tokenUri = &quot;https://cloud-api.loginradius.com/sso/oidc/v2/{loginradius-site-name}/token&quot;</span></code></pre>\n<h2 id=\"create-an-oidc-app-in-loginradius\" style=\"position:relative;\"><a href=\"#create-an-oidc-app-in-loginradius\" aria-label=\"create an oidc app in loginradius permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Create an OIDC app in LoginRadius</h2>\n<p>Login to your LoginRadius account or <a href=\"https://www.loginradius.com/\">signup here</a> if you don't have one. </p>\n<p>Once you log in you can see by default, one application will be created for you. Otherwise, you can create a new application here from the following screen by clicking <code>New App</code>.</p>\n<p><img src=\"/88ef8789fadffc46e2a255a6fb80fcdb/loginradius-dashboard.webp\" alt=\"loginradius-dashboard.webp\"></p>\n<p>I will be using the existing application itself for this demo as I am using a free plan. In the free plan, you can create only one application (no need for card details).</p>\n<p>Upgrade your application subscription to the <code>Developer Pro</code> Plan to configure OIDC. (<code>Developer Pro</code> Plan is available with 21 days trial).</p>\n<p><img src=\"/02e6331840d1bcb860ee3fce59596faa/loginradius-upgrade-subscription-1.webp\" alt=\"loginradius-upgrade-subscription-1.webp\"></p>\n<p><img src=\"/fb33387fac84b2a97c35d480069f3319/loginradius-upgrade-subscription-2.webp\" alt=\"loginradius-upgrade-subscription-2.webp\"></p>\n<p>Now click on <code>Select &#x26; Configure</code> on your application and navigate to the <code>Integration</code> Section and Configure <code>Open ID</code> configuration. You can find step-by-step details to <a href=\"https://www.loginradius.com/developers/\">configure OIDC</a> here.</p>\n<p>Once you configure these <code>conf/application.conf</code> will look something like this.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"scala\" data-index=\"11\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"># This is the main configuration file for the application.</span>\n<span class=\"grvsc-line\"># https://www.playframework.com/documentation/latest/ConfigFile</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">play {</span>\n<span class=\"grvsc-line\">  modules {</span>\n<span class=\"grvsc-line\">    enabled += modules.SecurityModule</span>\n<span class=\"grvsc-line\">  }</span>\n<span class=\"grvsc-line\">}</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">baseUrl = &quot;http://localhost:9000&quot;</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">oidc.discoveryUri = &quot;https://cloud-api.loginradius.com/sso/oidc/v2/dev-svv3qlcj2y/pac4j-play-loginradius-demo/.well-known/openid-configuration&quot;</span>\n<span class=\"grvsc-line\">oidc.clientId = &quot;8ce24413-9b7e-4282-9f5b-e0e5ec13a42a&quot;</span>\n<span class=\"grvsc-line\">oidc.clientSecret = &quot;c9c61f6e-325f-40d6-89fd-696d17f970eb&quot;</span>\n<span class=\"grvsc-line\">oidc.tokenUri = &quot;https://cloud-api.loginradius.com/sso/oidc/v2/dev-svv3qlcj2y/token&quot;</span>\n<span class=\"grvsc-line\"># Site Name - dev-svv3qlcj2y</span>\n<span class=\"grvsc-line\"># App Name - pac4j-play-loginradius-demo</span></code></pre>\n<h2 id=\"time-to-test-complete-integration\" style=\"position:relative;\"><a href=\"#time-to-test-complete-integration\" aria-label=\"time to test complete integration permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Time to test complete Integration</h2>\n<p>Let's run our application using <code>sbt clean run</code> and visit <code>http://localhost:9000</code>. The Home page will look like this.</p>\n<h3 id=\"home-page\" style=\"position:relative;\"><a href=\"#home-page\" aria-label=\"home page permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Home Page</h3>\n<p><img src=\"/4c35100213251fe1d18a6e1aae565d2b/home-page.webp\" alt=\"home-page.webp\"></p>\n<h3 id=\"loginradius-auth-page-idx\" style=\"position:relative;\"><a href=\"#loginradius-auth-page-idx\" aria-label=\"loginradius auth page idx permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>LoginRadius Auth Page (IDX)</h3>\n<p>Now click on the <code>protected url by OIDC</code> link on the home page that will redirect you to the LoginRadius Auth Page (IDX), which you configured.</p>\n<p><img src=\"/af92ab759d2f4b543a466933707a44af/loginradius-consent-page.webp\" alt=\"loginradius-consent-page.webp\"></p>\n<h3 id=\"redirect-to-protected-index-page\" style=\"position:relative;\"><a href=\"#redirect-to-protected-index-page\" aria-label=\"redirect to protected index page permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Redirect to Protected Index Page</h3>\n<p>On successful login from the above step, you will be redirected to the <code>protectedindex.scala.html</code> page.</p>\n<p><img src=\"/1083cf7a089a7c3324dcc7b853351249/loginradius-protected-index-page.webp\" alt=\"loginradius-protected-index-page.webp\"></p>\n<h3 id=\"logout-action\" style=\"position:relative;\"><a href=\"#logout-action\" aria-label=\"logout action permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Logout Action</h3>\n<p><a href=\"https://github.com/pac4j/play-pac4j\">play-pac4j</a> provides out of the box <code>LogoutController</code> which can be used to handle logout flows. It has <code>logout</code> functionality which has the logout logic implementation to clear the session. Below is the sample <code>logout</code> functionality from <code>org.pac4j.play.LogoutController</code> play-pac4j module.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"java\" data-index=\"12\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">public</span><span class=\"mtk1\"> </span><span class=\"mtk10\">CompletionStage</span><span class=\"mtk1\">&lt;Result&gt; </span><span class=\"mtk11\">logout</span><span class=\"mtk1\">(</span><span class=\"mtk4\">final</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Http</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Request</span><span class=\"mtk1\"> request) {</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">final</span><span class=\"mtk1\"> </span><span class=\"mtk10\">HttpActionAdapter</span><span class=\"mtk1\"> </span><span class=\"mtk12\">bestAdapter</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">FindBest</span><span class=\"mtk1\">.</span><span class=\"mtk11\">httpActionAdapter</span><span class=\"mtk1\">(</span><span class=\"mtk4\">null</span><span class=\"mtk1\">, config, </span><span class=\"mtk12\">PlayHttpActionAdapter</span><span class=\"mtk1\">.</span><span class=\"mtk12\">INSTANCE</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">final</span><span class=\"mtk1\"> </span><span class=\"mtk10\">LogoutLogic</span><span class=\"mtk1\"> </span><span class=\"mtk12\">bestLogic</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">FindBest</span><span class=\"mtk1\">.</span><span class=\"mtk11\">logoutLogic</span><span class=\"mtk1\">(logoutLogic, config, </span><span class=\"mtk12\">DefaultLogoutLogic</span><span class=\"mtk1\">.</span><span class=\"mtk12\">INSTANCE</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">final</span><span class=\"mtk1\"> </span><span class=\"mtk10\">WebContext</span><span class=\"mtk1\"> </span><span class=\"mtk12\">context</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">FindBest</span><span class=\"mtk1\">.</span><span class=\"mtk11\">webContextFactory</span><span class=\"mtk1\">(</span><span class=\"mtk4\">null</span><span class=\"mtk1\">, config, </span><span class=\"mtk12\">PlayContextFactory</span><span class=\"mtk1\">.</span><span class=\"mtk12\">INSTANCE</span><span class=\"mtk1\">).</span><span class=\"mtk11\">newContext</span><span class=\"mtk1\">(request);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">CompletableFuture</span><span class=\"mtk1\">.</span><span class=\"mtk11\">supplyAsync</span><span class=\"mtk1\">(() </span><span class=\"mtk4\">-&gt;</span><span class=\"mtk1\"> (Result) </span><span class=\"mtk12\">bestLogic</span><span class=\"mtk1\">.</span><span class=\"mtk11\">perform</span><span class=\"mtk1\">(context, sessionStore, config, bestAdapter, </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">defaultUrl</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">logoutUrlPattern</span><span class=\"mtk1\">, </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">localLogout</span><span class=\"mtk1\">, </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">destroySession</span><span class=\"mtk1\">, </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">centralLogout</span><span class=\"mtk1\">), </span><span class=\"mtk12\">ec</span><span class=\"mtk1\">.</span><span class=\"mtk11\">current</span><span class=\"mtk1\">());</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span></code></pre>\n<p>So to use this LogoutController, we just need to initialize it and define logout route for the same in our <code>routes</code>. We already initialized LoginController in <code>SecurityModule.java</code>.</p>\n<h4 id=\"a-initialize-logoutcontroller\" style=\"position:relative;\"><a href=\"#a-initialize-logoutcontroller\" aria-label=\"a initialize logoutcontroller permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>a. Initialize LogoutController</h4>\n<ul>\n<li>You can configure default url which application needs to redirect after <code>logout</code> action.</li>\n</ul>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"java\" data-index=\"13\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk3\">// logout</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">final</span><span class=\"mtk1\"> </span><span class=\"mtk10\">LogoutController</span><span class=\"mtk1\"> </span><span class=\"mtk12\">logoutController</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">new</span><span class=\"mtk1\"> </span><span class=\"mtk11\">LogoutController</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">logoutController</span><span class=\"mtk1\">.</span><span class=\"mtk11\">setDefaultUrl</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/?defaulturlafterlogout&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk11\">bind</span><span class=\"mtk1\">(</span><span class=\"mtk12\">LogoutController</span><span class=\"mtk1\">.</span><span class=\"mtk12\">class</span><span class=\"mtk1\">).</span><span class=\"mtk11\">toInstance</span><span class=\"mtk1\">(logoutController);</span></span></code></pre>\n<h4 id=\"b-define-route-for-logoutcontroller\" style=\"position:relative;\"><a href=\"#b-define-route-for-logoutcontroller\" aria-label=\"b define route for logoutcontroller permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>b. Define Route for LogoutController</h4>\n<ul>\n<li>We already configured <code>/logout</code> Route using <code>LogoutController</code> in <code>conf/routes</code>.</li>\n</ul>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"scala\" data-index=\"14\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">GET     /logout                     @org.pac4j.play.LogoutController.logout(request: Request)</span></code></pre>\n<p>On Clicking <code>logout</code> in our application, the session will be cleared and you will be redirected to the Home page based on our configuration. </p>\n<h2 id=\"source-code\" style=\"position:relative;\"><a href=\"#source-code\" aria-label=\"source code permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Source Code</h2>\n<p>You can see the full source code for the application developed in this tutorial on <a href=\"https://github.com/vishnuchilamakuru/loginradius-play-oidc-example\">GitHub</a>.</p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk15 { color: #C586C0; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk3 { color: #6A9955; }\n  .dark-default-dark .mtk17 { color: #808080; }\n</style>","frontmatter":{"date":"June 25, 2021","updated_date":null,"title":"Add Authentication to Play Framework With OIDC and LoginRadius","tags":["OIDC","Java","pac4j","Play Framework","Authentication"],"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/20973f3ab172cea4306baad7dd6cba11/58556/pac4j-authentication.webp","srcSet":"/static/20973f3ab172cea4306baad7dd6cba11/61e93/pac4j-authentication.webp 200w,\n/static/20973f3ab172cea4306baad7dd6cba11/1f5c5/pac4j-authentication.webp 400w,\n/static/20973f3ab172cea4306baad7dd6cba11/58556/pac4j-authentication.webp 800w,\n/static/20973f3ab172cea4306baad7dd6cba11/210c1/pac4j-authentication.webp 900w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Vishnu Chilamakuru","github":"vishnuchilamakuru","avatar":null}}}}]}},"pageContext":{"tag":"pac4j"}},"staticQueryHashes":["1171199041","1384082988","2100481360","23180105","528864852"]}