{"id":60699,"date":"2016-10-17T09:48:45","date_gmt":"2016-10-17T06:48:45","guid":{"rendered":"http:\/\/www.javacodegeeks.com\/?p=60699"},"modified":"2016-10-24T11:04:09","modified_gmt":"2016-10-24T08:04:09","slug":"single-sign-java-20-minutes-spring-boot-heroku","status":"publish","type":"post","link":"https:\/\/www.javacodegeeks.com\/2016\/10\/single-sign-java-20-minutes-spring-boot-heroku.html","title":{"rendered":"Single Sign-on for Java in 20 Minutes with Spring Boot and Heroku"},"content":{"rendered":"<p><span style=\"font-size: 20px;\">Building Identity Management, including authentication and authorization? Try Stormpath! Our REST API and <a href=\"https:\/\/docs.stormpath.com\/java\/?utm_source=java-code-geeks&#038;utm_medium=post&#038;utm_content=spring-boot-id-site&#038;utm_campaign=spring-java-2016\">robust Java SDK support<\/a> can eliminate your security risk and can be implemented in minutes. <a href=\"https:\/\/api.stormpath.com\/register?utm_source=java-code-geeks&#038;utm_medium=post&#038;utm_content=spring-boot-id-site&#038;utm_campaign=spring-java-2016\">Sign up<\/a>, and never build auth again!<\/span><\/p>\n<h2>Massive Update<\/h2>\n<p>The code I originally wrote for this post is more suited to non-Spring Boot environments.<\/p>\n<p>Stormpath\u2019s existing Spring Boot integration for its <a href=\"https:\/\/docs.stormpath.com\/guides\/using-id-site\/?utm_source=java-code-geeks&amp;utm_medium=post&amp;utm_content=spring-boot-id-site&amp;utm_campaign=spring-java-2016\">IDSite<\/a> service makes writing code for it a snap. It takes advantage of all the auto configuration that Spring Boot has to offer.<\/p>\n<p>If your new to this post, read on. If you\u2019ve read it before, jump on down to the <a href=\"https:\/\/stormpath.com\/blog\/spring-boot_id-site_heroku#update-your-spring-boot-webapp?ring Boot Starter Web autm_source=java-code-geeks&amp;utm_medium=post&amp;utm_content=spring-boot-id-site&amp;utm_campaign=spring-java-2016\">Update Your Spring Boot Webapp<\/a> section. You\u2019ll see that the <code>RestrictedController<\/code> has been reduced from 40 lines down to 15 and from 4 methods down to 1.<\/p>\n<h2>The Main Event \u2013 Easy Single Sign-on<\/h2>\n<p>I love how Java keeps reinventing itself to stay current and relevant (I can hear all my Node.js and Ruby friends groaning). The ecosystem that supports Java is keeping pace with new developments as well. Today, it\u2019s as easy today to build, test and deploy a rich Java web app as quickly as in Python or Node.js (more groans).<\/p>\n<p>One piece of that is Spring Boot, which makes building and launching a Java webapp in minutes a reality. Heroku\u2019s focus on Java support also speeds things along.<\/p>\n<p>Finally, Stormpath means developers don\u2019t have to build authentication and authorization workflows. Stormpath\u2019s identity API and single sign-on functionality (<a href=\"https:\/\/docs.stormpath.com\/guides\/using-id-site\/?utm_source=java-code-geeks&amp;utm_medium=post&amp;utm_content=spring-boot-id-site&amp;utm_campaign=spring-java-2016\">via IDSite<\/a>) provide out-of-the-box account registration, login, email workflows and single sign-on across applications. These flows include default forms and views, all of which are customizable.<\/p>\n<p>In this post, we will put all that together and get the added bonus of <a href=\"https:\/\/stormpath.com\/product\/sso?utm_source=java-code-geeks&amp;utm_medium=post&amp;utm_content=spring-boot-id-site&amp;utm_campaign=spring-java-2016\">single sign-on<\/a> across your applications \u2013 all within 20 minutes.<\/p>\n<p>Read on \u2013 tick tock!<br \/>\n<span id=\"more-2254\"><\/span><\/p>\n<p>Here are the prerequisites you need for this tutorial:<\/p>\n<ul>\n<li>Gradle 2.x\n<ul>\n<li>On Mac: <code>brew install gradle<\/code><\/li>\n<\/ul>\n<\/li>\n<li>Heroku\n<ul>\n<li>Create a <a href=\"http:\/\/heroku.com\/\">Heroku<\/a> account<\/li>\n<li>Install the <a href=\"https:\/\/toolbelt.heroku.com\/\">Heroku Toolbelt<\/a><\/li>\n<li>Login to Heroku: <code>heroku login<\/code><\/li>\n<\/ul>\n<\/li>\n<li>A Stormpath Account (which we will also cover below)<\/li>\n<\/ul>\n<p><strong>Note<\/strong>: You can just as easily use <a href=\"https:\/\/maven.apache.org\/\">Maven<\/a>. The <a href=\"https:\/\/github.com\/stormpath\/spring-boot-idsite-sso-demo\">source code<\/a> that goes with this post includes a <code>pom.xml<\/code>, if that\u2019s your prefered build tool.<\/p>\n<p>To make it super easy, we\u2019ve added a handy Heroku deploy button to each example, so you can see it in action right away. If this takes you more than 20 minutes, please let us know what held you up in the comments. We love feedback.<\/p>\n<h2>Launch Spring Boot \u2013 5 Minute Tutorial<\/h2>\n<p><strong>Note<\/strong>: If you are already well versed in the world of Spring Boot, you may want to <a href=\"https:\/\/stormpath.com\/blog\/spring-boot_id-site_heroku#add_stormpath?utm_source=java-code-geeks&amp;utm_medium=post&amp;utm_content=spring-boot-id-site&amp;utm_campaign=spring-java-2016\">jump<\/a> to the next section. There \u2013 I just saved you 5 minutes. Your welcome.<\/p>\n<p>This section uses the <a href=\"https:\/\/github.com\/stormpath\/spring-boot-idsite-sso-demo\/tree\/SpringBootBasic\">SpringBootBasic<\/a> tag in the github repository.<\/p>\n<p><a href=\"https:\/\/signup.heroku.com\/deploy?redirect-url=https%3A%2F%2Fdashboard.heroku.com%2Fnew%3Fbutton-url%3Dhttps%253A%252F%252Fstormpath.com%252Fblog%252Fspring-boot_id-site_heroku%26template%3Dhttps%253A%252F%252Fgithub.com%252Fstormpath%252Fspring-boot-idsite-sso-demo%252Ftree%252FSpringBootBasic\"><img decoding=\"async\" style=\"border:none\" class=\"aligncenter size-full wp-image-60700\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/button.png\" alt=\"button\" width=\"147\" height=\"32\" \/><\/a><\/p>\n<p>Spring Boot enables you to fire up a fully functioning Java web application just like you would start a simple Java application. It has a <code>main<\/code> method and everything. For instance, the<code>@SpringBootlApplication<\/code> annotation does everything that the <code>@Configuration<\/code>,<code>@EnableAutoConfiguration<\/code> and <code>@ComponentScan<\/code> annotations (with their default attributes) do in a vanilla Spring application.<\/p>\n<p>What makes Spring Boot work so well and so easily are Starter packages that add in functionality, including default configuration. The Stormpath Spring Boot Thymeleaf Starter we will use further on bakes in all of the Stormpath functionality for creating new users, logging in and changing passwords. All you do is reference a single jar in your <code>build.gradle<\/code> or <code>pom.xml<\/code> file.<\/p>\n<p>For our basic example, we are going to include the core Spring Boot Starter Web and the <a href=\"http:\/\/www.thymeleaf.org\/\">Thymeleaf<\/a> Spring Boot Starter. Thymeleaf is a modern HTML 5 Java templating engine.<\/p>\n<p>Here\u2019s our <code>build.gradle<\/code>:<\/p>\n<pre class=\"brush:java\">buildscript {\r\n    repositories {\r\n        mavenCentral()\r\n    }\r\n    dependencies {\r\n        classpath(\"org.springframework.boot:spring-boot-gradle-plugin:1.2.5.RELEASE\")\r\n    }\r\n}\r\n \r\napply plugin: 'java'\r\napply plugin: 'maven'\r\napply plugin: 'spring-boot'\r\n \r\ngroup = 'com.stormpath'\r\nversion = '0.1.0'\r\n \r\nsourceCompatibility = 1.8\r\ntargetCompatibility = 1.8\r\n \r\nrepositories {\r\n    mavenCentral()\r\n}\r\n \r\ndependencies {\r\n    compile group: 'org.springframework.boot', name: 'spring-boot-starter-web', version:'1.2.5.RELEASE'\r\n    compile group: 'org.springframework.boot', name: 'spring-boot-starter-thymeleaf', version:'1.2.5.RELEASE'\r\n}<\/pre>\n<p>There are three more files we need to get our basic Spring Boot app going.<\/p>\n<p><code>IDSiteDemoApplication.java<\/code> is the application\u2019s entry point:<\/p>\n<pre class=\"brush:java\">package com.stormpath.idsite_demo;\r\n \r\nimport org.springframework.boot.SpringApplication;\r\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\r\n \r\n@SpringBootApplication\r\npublic class IDSiteDemoApplication {\r\n    public static void main(String[] args) {\r\n        SpringApplication.run(IDSiteDemoApplication.class, args);\r\n    }\r\n}<\/pre>\n<p>The <code>@SpringBootApplication<\/code> annotation sets up all the configuration necessary to launch the application.<\/p>\n<p><code>HomeController.java<\/code> maps a URI and resolves to a Thymeleaf template:<\/p>\n<pre class=\"brush:java\">package com.stormpath.idsite_demo.controllers;\r\n \r\nimport org.springframework.stereotype.Controller;\r\nimport org.springframework.web.bind.annotation.RequestMapping;\r\n \r\n@Controller\r\npublic class HomeController {\r\n    @RequestMapping(\"\/\")\r\n    public String home() {\r\n        return \"home\";\r\n    }\r\n}<\/pre>\n<p>The <code>@Controller<\/code> and <code>@RequestMapping<\/code> annotations set this class up as a controller and configure it to handle requests at the <code>\/<\/code> URI. Simply returning the String <code>home<\/code> hooks into the Thymeleaf template architecture which leads us to our final file:<\/p>\n<p><code>home.html<\/code> located in the <code>templates<\/code> folder is the template that will be rendered when browsing to <code>\/<\/code>:<\/p>\n<pre class=\"brush:xml\">&lt;!DOCTYPE html&gt;\r\n&lt;html xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\" xmlns:th=\"http:\/\/www.thymeleaf.org\"&gt;\r\n    &lt;head&gt;\r\n        &lt;th:block th:include=\"fragments\/head :: head\"\/&gt;\r\n    &lt;\/head&gt;\r\n    &lt;body&gt;\r\n        &lt;div class=\"container-fluid\"&gt;\r\n            &lt;div class=\"row\"&gt;\r\n                &lt;div class=\"box col-md-6 col-md-offset-3\"&gt;\r\n                    &lt;div class=\"stormpath-header\"&gt;\r\n                        &lt;img src=\"http:\/\/stormpath.com\/images\/template\/logo-nav.png\"\/&gt;\r\n                    &lt;\/div&gt;\r\n                    &lt;h1&gt;Hello!&lt;\/h1&gt;\r\n                &lt;\/div&gt;\r\n            &lt;\/div&gt;\r\n        &lt;\/div&gt;\r\n    &lt;\/body&gt;\r\n&lt;\/html&gt;<\/pre>\n<p><strong>Note<\/strong>: You may notice the <code>th:include<\/code> directive in the template above. This is part of the Thymeleaf architecture for including files in other files. The full source code for the example has the<code>templates\/fragments\/head.html<\/code> file.<\/p>\n<p>Alrighty, then. Let\u2019s round out this first 5 minutes by firing up this most basic of Spring Boot apps.<\/p>\n<p><code>gradle clean build<\/code> will do the trick. Then: <code>java -jar build\/libs\/idsite_demo-0.1.0.jar<\/code><\/p>\n<p><a href=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/build_it_one.gif\"><img decoding=\"async\" class=\"aligncenter wp-image-60701\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/build_it_one.gif\" alt=\"build_it_one\" width=\"860\" height=\"521\" \/><\/a><\/p>\n<h2>Add Stormpath for SpringBoot Authentication<\/h2>\n<p>This section uses the <a href=\"https:\/\/github.com\/stormpath\/spring-boot-idsite-sso-demo\/tree\/SpringBootStormpath\">SpringBootStormpath<\/a> tag in the github repository.<\/p>\n<p><a href=\"https:\/\/signup.heroku.com\/deploy?redirect-url=https%3A%2F%2Fdashboard.heroku.com%2Fnew%3Fbutton-url%3Dhttps%253A%252F%252Fstormpath.com%252Fblog%252Fspring-boot_id-site_heroku%26template%3Dhttps%253A%252F%252Fgithub.com%252Fstormpath%252Fspring-boot-idsite-sso-demo%252Ftree%252FSpringBootStormpath\"><img decoding=\"async\" style=\"border:none\" class=\"aligncenter size-full wp-image-60700\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/button.png\" alt=\"button\" width=\"147\" height=\"32\" \/><\/a><\/p>\n<p>In this section, we\u2019ll:<\/p>\n<ul>\n<li>Create a Stormpath Account<\/li>\n<li>Generate a Stormpath API Key Pair<\/li>\n<li>Add an Application to your Stormpath Account<\/li>\n<li>Update your Spring Boot webapp to show some Stormpath app information<\/li>\n<li>Fire it up and watch it work<\/li>\n<\/ul>\n<h3>Create a Stormpath Account<\/h3>\n<p>Go to the Stormpath <a href=\"https:\/\/api.stormpath.com\/register?utm_source=java-code-geeks&amp;utm_medium=post&amp;utm_content=spring-boot-id-site&amp;utm_campaign=spring-java-2016\">Registration page<\/a>. Enter your First and Last names, company, email and password.<\/p>\n<p><a href=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/spring-boot-heroku-register.png\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-60702\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/spring-boot-heroku-register.png\" alt=\"spring-boot-heroku-register\" width=\"778\" height=\"692\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/spring-boot-heroku-register.png 778w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/spring-boot-heroku-register-300x267.png 300w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/spring-boot-heroku-register-768x683.png 768w\" sizes=\"(max-width: 778px) 100vw, 778px\" \/><\/a><\/p>\n<p>Click Signup.<\/p>\n<p>Click the link in the verification email you receive. Then, you will see the tenant name that\u2019s been generated for you.<\/p>\n<p><a href=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/spring-boot-heroku-login.png\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-60703\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/spring-boot-heroku-login.png\" alt=\"spring-boot-heroku-login\" width=\"411\" height=\"582\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/spring-boot-heroku-login.png 411w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/spring-boot-heroku-login-212x300.png 212w\" sizes=\"(max-width: 411px) 100vw, 411px\" \/><\/a><\/p>\n<p>Login. Done.<\/p>\n<p><strong>Note<\/strong>: For more information on multi-tenant applications, we have a handy <a href=\"https:\/\/stormpath.com\/blog\/Multitenant-user-management-easy\/?utm_source=java-code-geeks&amp;utm_medium=post&amp;utm_content=spring-boot-id-site&amp;utm_campaign=spring-java-2016\">blog post<\/a> on it.<\/p>\n<h3>Generate a Stormpath API Key Pair<\/h3>\n<p>Once you log in to your Stormpath account, you will see this screen:<\/p>\n<p><a href=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/spring-boot-heroku-dashboard.png\"><img decoding=\"async\" class=\"aligncenter wp-image-60704\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/spring-boot-heroku-dashboard.png\" alt=\"spring-boot-heroku-dashboard\" width=\"860\" height=\"416\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/spring-boot-heroku-dashboard.png 1440w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/spring-boot-heroku-dashboard-300x145.png 300w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/spring-boot-heroku-dashboard-768x372.png 768w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/spring-boot-heroku-dashboard-1024x496.png 1024w\" sizes=\"(max-width: 860px) 100vw, 860px\" \/><\/a><\/p>\n<p>Click the <code>Create API Key<\/code> button.<\/p>\n<p><a href=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/api_key.png\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-60705\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/api_key.png\" alt=\"api_key\" width=\"570\" height=\"314\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/api_key.png 570w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/api_key-300x165.png 300w\" sizes=\"(max-width: 570px) 100vw, 570px\" \/><\/a><\/p>\n<p>Click the <code>Create API Key<\/code> button and save the file.<\/p>\n<p>The API Keys stored in that file are used to authenticate your application to Stormpath. In the file, there\u2019s an <code>apiKey.id<\/code> and a <code>apiKey.secret<\/code>. You would never want the <code>apiKey.secret<\/code> exposed. So, for instance, you would never want to have the api keys file checked into a git repository. When we deploy to Heroku later on, I will show you how to configure your app to use the api keys without having to have them in the git respository.<\/p>\n<p>Stormpath uses well documented configuration defaults to make working with our APIs super easy. One of these defaults is the api key file location. The Java SDK will automatically look for the file in your home directory:<\/p>\n<pre class=\"brush:bash\">~\/.stormpath\/apiKey.properties<\/pre>\n<p>If you copy the file you downloaded to that path, no additional configuration is required to connect to Stormpath from your application.<div style=\"display:inline-block; margin: 15px 0;\"> <div id=\"adngin-JavaCodeGeeks_incontent_video-0\" style=\"display:inline-block;\"><\/div> <\/div><\/p>\n<h3>Add an Application to Your Stormpath Account<\/h3>\n<p>Back on the admin dashboard, click the Applications tab.<\/p>\n<p><a href=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/applications.png\"><img decoding=\"async\" class=\"aligncenter wp-image-60706\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/applications.png\" alt=\"applications\" width=\"860\" height=\"390\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/applications.png 1439w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/applications-300x136.png 300w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/applications-768x348.png 768w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/applications-1024x464.png 1024w\" sizes=\"(max-width: 860px) 100vw, 860px\" \/><\/a><\/p>\n<p>You will notice that there are two applications already present: <code>My Application<\/code> and <code>Stormpath<\/code>. They were setup automatically when you registered for Stormpath. Without any other Stormpath applications defined, no further configuration is needed for your Spring Boot application. By default, it will connect to the <code>My Application<\/code> instance already defined.<\/p>\n<p>However, the ultimate goal here is to get some Single Signon goodness and in order to do that, we\u2019ll need more than one application to sign in to.<\/p>\n<p>So, let\u2019s create another Stormpath application. Click the <code>Create Application<\/code> button.<\/p>\n<p><a href=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/new_application.png\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-60707\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/new_application.png\" alt=\"new_application\" width=\"583\" height=\"763\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/new_application.png 583w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/new_application-229x300.png 229w\" sizes=\"(max-width: 583px) 100vw, 583px\" \/><\/a><\/p>\n<p>Let\u2019s break down the options here.<\/p>\n<p>Name and (optional) description are self explanatory. And, it makes sense that we want this application Enabled.<\/p>\n<p>By default, the <code>Create new Directory<\/code> checkbox is checked. For our example, I\u2019ve unchecked this option. Rather, I\u2019ve checked the <code>Map Account Stores to this Application<\/code> checkbox and chosen the<code>My Application Directory<\/code>. Finally, I\u2019ve clicked the <code>DEFAULT ACCOUNT LOCATION<\/code> and <code>DEFAULT GROUP LOCATION<\/code> radio buttons.<\/p>\n<p>So, what\u2019s going on here? The way that Stormpath is organized, an application can use any number of directories as its Account Stores. A Stormpath directory is just a bucket that contains accounts and groups. For our purposes, we can use the directory that was automatically created for us when we registered called <code>My Application Directory<\/code>. In the bonus section below, I will show you how to create a specific type of directory to add Google authentication to your app. Spoiler alert: It\u2019s super easy.<\/p>\n<h3>Update Your Spring Boot Webapp<\/h3>\n<p>Let\u2019s hook up our basic Spring Boot app to Stormpath to show some Stormpath app information. This will lay the foundation for being able to integrate with the ID Site service.<\/p>\n<p>Take a look at our <code>HomeController<\/code>:<\/p>\n<pre class=\"brush:java\">package com.stormpath.idsite_demo.controllers;\r\n \r\n@Controller\r\npublic class HomeController {\r\n    @Autowired\r\n    Application app;\r\n \r\n    @RequestMapping(\"\/\")\r\n    public String home(Model model) {\r\n        model.addAttribute(\"appName\", app.getName());\r\n        model.addAttribute(\"appDescription\", app.getDescription());\r\n \r\n        return \"home\";\r\n    }\r\n}<\/pre>\n<p>We\u2019ve now taken advantage of Spring\u2019s <code>@Autowired<\/code> capability to give us a handle to the Stormpath<code>Application<\/code> object. Using that, we set the Application\u2019s name and description in the <code>Model<\/code> object which will be passed on to our template.<\/p>\n<p>This brings us to our next change, the <code>home.html<\/code> Thymeleaf template:<\/p>\n<pre class=\"brush:xml\">&lt;!DOCTYPE html&gt;\r\n&lt;html xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\" xmlns:th=\"http:\/\/www.thymeleaf.org\"&gt;\r\n    &lt;head&gt;\r\n        &lt;th:block th:include=\"fragments\/head :: head\"\/&gt;\r\n    &lt;\/head&gt;\r\n    &lt;body&gt;\r\n        &lt;div class=\"container-fluid\"&gt;\r\n            &lt;div class=\"row\"&gt;\r\n                &lt;div class=\"box col-md-6 col-md-offset-3\"&gt;\r\n                    &lt;div class=\"stormpath-header\"&gt;\r\n                        &lt;img src=\"http:\/\/stormpath.com\/images\/template\/logo-nav.png\"\/&gt;\r\n                    &lt;\/div&gt;\r\n                    &lt;h1 th:inline=\"text\"&gt;Hello! Welcome to App: [[${appName}]]&lt;\/h1&gt;\r\n \r\n                    &lt;h3 th:inline=\"text\"&gt;[[${appDescription}]]&lt;\/h3&gt;\r\n                &lt;\/div&gt;\r\n            &lt;\/div&gt;\r\n        &lt;\/div&gt;\r\n    &lt;\/body&gt;\r\n&lt;\/html&gt;<\/pre>\n<p>Using the Thymeleaf notation to pull information out of the model, we are referencing <code>[[${appName}]]<\/code>and <code>[[${appDescription}]]<\/code>.<\/p>\n<p>Finally, we\u2019ll make a small (but powerful) update to out <code>build.gradle<\/code> file. We are changing this line:<\/p>\n<pre class=\"brush:bash\">compile group: 'org.springframework.boot', name: 'spring-boot-starter-thymeleaf', version:'1.2.5.RELEASE'\r\n<\/pre>\n<p>to this:<\/p>\n<pre class=\"brush:bash\">compile group: 'com.stormpath.spring', name: 'spring-boot-starter-stormpath-thymeleaf', version:'1.0.RC4.5'<\/pre>\n<p>We\u2019ve swapped out Spring\u2019s Thymleaf Spring Boot Starter for Stormpath\u2019s. Here\u2019s the cool bit: everything needed to interact with the Stormpath Java SDK is included in this Starter.<\/p>\n<p>There\u2019s a total of 7 lines that have changed in our application files and one file,<code>application.properties<\/code> that we\u2019ve added in order to start hooking in to Stormpath.<\/p>\n<h3>Build Your Java Web Application<\/h3>\n<p>One extra bit of information we will need here is the URL to the Stormpath Application you created.<\/p>\n<p>You can find this from the admin dashboard by navigating to your Application.<\/p>\n<p><a href=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/application_id.png\"><img decoding=\"async\" class=\"aligncenter wp-image-60708\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/application_id.png\" alt=\"application_id\" width=\"860\" height=\"390\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/application_id.png 1440w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/application_id-300x136.png 300w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/application_id-768x348.png 768w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/application_id-1024x464.png 1024w\" sizes=\"(max-width: 860px) 100vw, 860px\" \/><\/a><\/p>\n<p>Assuming that you put your api key file in the default location of <code>~\/.stormpath\/apiKey.properties<\/code>, this is all you need to do run this example:<\/p>\n<pre class=\"brush:bash\">gradle clean build\r\nSTORMPATH_APPLICATION_HREF=https:\/\/api.stormpath.com\/v1\/applications\/6bHOGj63WM8cfC2nhD3Pki \\\r\n  java -jar build\/libs\/idsite_demo-0.1.0.jar<\/pre>\n<p>Of course, you would put your own <code>STORMPATH_APPLICATION_HREF<\/code> in.<\/p>\n<p><a href=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/app_info.png\"><img decoding=\"async\" class=\"aligncenter wp-image-60709\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/app_info.png\" alt=\"app_info\" width=\"860\" height=\"592\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/app_info.png 1026w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/app_info-300x206.png 300w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/app_info-768x528.png 768w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/app_info-1024x705.png 1024w\" sizes=\"(max-width: 860px) 100vw, 860px\" \/><\/a><\/p>\n<p>You can see that the page in the browser is now displaying the information from the Stormpath Application that we created.<\/p>\n<h2>Stormpath Single Sign-On with IDSite\u2026<\/h2>\n<p>\u2026you guessed it. In Five Minutes.<\/p>\n<p>This section uses the <a href=\"https:\/\/github.com\/stormpath\/spring-boot-idsite-sso-demo\/tree\/SpringBootStormpathIDSite\">SpringBootStormpathIDSite<\/a> tag in the github repository.<\/p>\n<p><a href=\"https:\/\/signup.heroku.com\/deploy?redirect-url=https%3A%2F%2Fdashboard.heroku.com%2Fnew%3Fbutton-url%3Dhttps%253A%252F%252Fstormpath.com%252Fblog%252Fspring-boot_id-site_heroku%26template%3Dhttps%253A%252F%252Fgithub.com%252Fstormpath%252Fspring-boot-idsite-sso-demo%252Ftree%252FSpringBootStormpathIDSite\"><img decoding=\"async\" style=\"border:none\" class=\"aligncenter size-full wp-image-60700\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/button.png\" alt=\"button\" width=\"147\" height=\"32\" \/><\/a><\/p>\n<p>You may have had the experience of adding authentication and authorization to your applications. Maybe you did it upfront. Maybe it was something you said you\u2019d get to \u2013 eventually. Either way it\u2019s a pain. And, it has nothing to do with the problem you are trying to solve. It is critical and necessary, though.<\/p>\n<p>In this section, we are going to add the ability to create new users, login, restrict access to a page to only those users that are logged in and change your password. And, we are going to do it with minimal coding and minimal configuration.<\/p>\n<h3>ID Site Configuration<\/h3>\n<p>First, we\u2019ll setup IDSite from the admin dashboard. Click the ID Site tab.<\/p>\n<p><a href=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/id_site_1.png\"><img decoding=\"async\" class=\"aligncenter wp-image-60710\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/id_site_1.png\" alt=\"id_site_1\" width=\"860\" height=\"523\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/id_site_1.png 2162w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/id_site_1-300x182.png 300w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/id_site_1-768x467.png 768w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/id_site_1-1024x622.png 1024w\" sizes=\"(max-width: 860px) 100vw, 860px\" \/><\/a><\/p>\n<p>As you scroll around, you will notice that there are a number of fields with the label <code>Upgrade Required<\/code>. The basic ID Site functionality can be used with our free tier, as we will see momentarily. Having a custom domain or customizing the templates used for authentication requires a paid subscription.<\/p>\n<p>Here, we are simply going to update two fields and save the settings.<\/p>\n<p><a href=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/id_site_2.png\"><img decoding=\"async\" class=\"aligncenter wp-image-60711\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/id_site_2.png\" alt=\"id_site_2\" width=\"860\" height=\"523\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/id_site_2.png 2160w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/id_site_2-300x183.png 300w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/id_site_2-768x467.png 768w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/id_site_2-1024x623.png 1024w\" sizes=\"(max-width: 860px) 100vw, 860px\" \/><\/a><\/p>\n<p>For security, you must specify a list of URLs that are allowed to make connections to your ID Site.<\/p>\n<p>Enter <code>http:\/\/localhost:8080<\/code> in the <code>Authorized Javascript Origin URLs<\/code> field.<\/p>\n<p>For the security reasons, you must specify a list of authorized redirect URLs.<\/p>\n<p>Enter <code>http:\/\/localhost:8080\/<\/code> and, on a separate line, <code>http:\/\/localhost:8080\/idSiteResult<\/code> in the<code>Authorized Redirect URLs<\/code> field.<\/p>\n<p>Click the <code>Save<\/code> button. That\u2019s all that\u2019s necessary to configure your ID Site to enable authentication and authorization in your app.<\/p>\n<p>Let\u2019s take a step back and use a precious 30 seconds of our 5 minutes to look at the mechanism behind ID Site.<\/p>\n<p>When a user attempts to access a restricted area of your website, they will be redirected to your ID Site, IF they do not already have an active session.<\/p>\n<p>They will be presented with a familiar login form complete with options to create a new user and to reset their password.<\/p>\n<p><a href=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/id_site_login.png\"><img decoding=\"async\" class=\"aligncenter wp-image-60712\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/id_site_login.png\" alt=\"id_site_login\" width=\"860\" height=\"534\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/id_site_login.png 1304w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/id_site_login-300x186.png 300w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/id_site_login-768x477.png 768w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/id_site_login-1024x636.png 1024w\" sizes=\"(max-width: 860px) 100vw, 860px\" \/><\/a><\/p>\n<p>Where did this come from? Is it magic? It\u2019s part of what you get for using ID Site \u2013 all the authentication and authorization flows that you usually write on your own. Poorly. (ouch \u2013 that was a little harsh. But, seriously \u2013 how often do you read about security breaches due to poorly implemented auth code?)<\/p>\n<p>Once authenticated, they will be redirected back to the URL you specify and will be able to access that restricted content.<\/p>\n<p>This process will seem utterly familiar to your users \u2013 even mundane. And you will have accomplished it with very little configuration or coding.<\/p>\n<p><a name=\"update-your-spring-boot-webapp\"><\/a><\/p>\n<h3>Update Your Spring Boot Webapp<\/h3>\n<p>Enabling IDSite for your Spring Boot application is handled with a single property in<code>application.properties<\/code>. We\u2019ll also two additional lines to control flow.<\/p>\n<pre class=\"brush:bash\">stormpath.web.idSite.enabled = true\r\nstormpath.web.login.nextUri = \/restricted\/secret\r\nstormpath.web.logout.nextUri = \/?status=logout<\/pre>\n<p>Line 1 enables IDSite for you application. Yup. That\u2019s all it takes!<\/p>\n<p>IDSite has defaults standard auth flows. By default, <code>\/login<\/code> redirects to <code>\/<\/code> after a user is authenticated and <code>\/logout<\/code> redirects to <code>\/login?status=logout<\/code> after the session is destroyed.<\/p>\n<p>For our application, once a user is authenticated, we want them redirected back to<code>\/restricted\/secret<\/code>. And, once a user logs out, we will redirect them back to the front door with a status of <code>logout<\/code>. Lines 2 and 3 above accomplish this.<\/p>\n<p>We are adding a single line in to our <code>home.html<\/code> template that kicks off the whole login flow:<\/p>\n<pre class=\"brush:xml\">&lt;a class=\"btn btn-success\" href=\"\/restricted\/secret\"&gt;Click here for a secret message.&lt;\/a&gt;<\/pre>\n<p>We are going to add about 15 lines of code in a new controller \u2013 total \u2013 to hook into ID Site.<br \/>\nLet\u2019s take a look at that controller, <code>RestrictedController.java<\/code>.<\/p>\n<pre class=\"brush:java\">package com.stormpath.idsite_demo.controllers;\r\n \r\n@Controller\r\npublic class RestrictedController {\r\n    @Autowired\r\n    Application app;\r\n \r\n    @Value(\"#{ @environment['stormpath.sso.cross.link'] ?: '\/' }\")\r\n    private String crossLink;\r\n \r\n    @Value(\"#{ @environment['stormpath.sso.message.primary'] ?: 'Primary' }\")\r\n    private String messagePrimary;\r\n \r\n    @Value(\"#{ @environment['stormpath.sso.message.secondary'] ?: 'Secondary' }\")\r\n    private String messageSecondary;\r\n \r\n \r\n    @RequestMapping(\"\/restricted\/secret\")\r\n    public String secret(HttpServletRequest request, Model model) {\r\n        Account account = AccountResolver.INSTANCE.getAccount(request);\r\n \r\n        if (account == null) {\r\n            return \"redirect:\/login\";\r\n        }\r\n \r\n        model.addAttribute(\"appName\", app.getName());\r\n        model.addAttribute(\"crossLink\", crossLink);\r\n        model.addAttribute(\"messagePrimary\", messagePrimary);\r\n        model.addAttribute(\"messageSecondary\", messageSecondary);\r\n        return \"restricted\/secret\";\r\n    }\r\n}<\/pre>\n<p>Let\u2019s break this down:<\/p>\n<p>Lines 8, 11 and 14 make use of the standard Spring facility for injecting values.<\/p>\n<p>Referencing environment variables ala <code>@environment['stormpath.sso.message.primary']<\/code> pulls in properties found in <code>applications.properties<\/code>.<\/p>\n<p>Here\u2019s the great part: Stormpath has a built in facility for converting system environment variables into application environment variables. This makes it super easy for us to set environment variables in a deployment environment like Heroku.<\/p>\n<p>Here\u2019s how it works: system environment variables are converted to lowercase and underscores are replaced with periods.<\/p>\n<p>So, <code>STORMPATH_SSO_MESSAGE_PRIMARY<\/code> is converted to <code>stormpath.sso.message.primary<\/code>.<\/p>\n<p><code>crossLink<\/code> is used in the context of single sign-on. This variable holds a fully qualified URL to the restricted page of another application that\u2019s setup in your IDSite.<\/p>\n<p><code>messagePrimary<\/code> and <code>messageSecondary<\/code> are used to set the messages that are displayed on the restricted page.<\/p>\n<p>These three variables make it possible for us to deploy the same codebase to multiple Heroku applications and show different messages on the restricted page.<\/p>\n<p>Here\u2019s what\u2019s going on behind the scenes with IDSite:<\/p>\n<ol>\n<li>On the home page, you click on the <code>Click here for a secret message.<\/code> which links to<code>\/restricted\/secret<\/code>.<\/li>\n<li>The <code>secret<\/code> method in <code>RestrictedController<\/code> is entered based on the <code>@RequestMapping<\/code> annotation.<\/li>\n<li>The <code>account<\/code> variable will come up as <code>null<\/code> since a session has not been established yet.<\/li>\n<li>Based on the conditional on line 22, you will be redirected to the <code>\/login<\/code> page.<\/li>\n<li>The login page is hosted by your IDSite.<\/li>\n<li>Once you enter your credentials and hit the <code>Login<\/code> button, you will be redirected back to your application.<\/li>\n<li>Your Spring Boot application automatically handles the <code>\/idSiteResult<\/code> callback that your IDSite redirects back to.<\/li>\n<li>Based on the settings in <code>applications.properties<\/code>, the built-in IDSite callback handler will redirect to<code>\/restricted\/secret<\/code><\/li>\n<li>This time through, there is a session and the <code>account<\/code> variable will not be <code>null<\/code>.<\/li>\n<li>Finally, the <code>restricted\/secret<\/code> template will be returned.<\/li>\n<\/ol>\n<p>All of the redirecting between lines 6 and 10 happens in the blink of an eye.<\/p>\n<p>Let\u2019s take a look at the new template, <code>restricted\/secret.html<\/code>:<\/p>\n<pre class=\"brush:xml\">&lt;!DOCTYPE html&gt;\r\n&lt;html xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\" xmlns:th=\"http:\/\/www.thymeleaf.org\"&gt;\r\n    &lt;head&gt;\r\n        &lt;title&gt;Hello World!&lt;\/title&gt;\r\n        &lt;th:block th:include=\"fragments\/head :: head\"\/&gt;\r\n    &lt;\/head&gt;\r\n    &lt;body&gt;\r\n    &lt;div class=\"container-fluid\"&gt;\r\n        &lt;div class=\"row\"&gt;\r\n            &lt;div class=\"box col-md-6 col-md-offset-3\"&gt;\r\n                &lt;div class=\"stormpath-header\"&gt;\r\n                    &lt;img src=\"http:\/\/stormpath.com\/images\/template\/logo-nav.png\"\/&gt;\r\n                &lt;\/div&gt;\r\n                &lt;h1 th:inline=\"text\"&gt;[[${appName}]] App&lt;\/h1&gt;\r\n \r\n                &lt;h1 th:inline=\"text\"&gt;Hey, [[${account.fullName}]]&lt;\/h1&gt;\r\n                &lt;h3 th:utext=\"${messagePrimary}\"&gt;Primary&lt;\/h3&gt;\r\n                &lt;h4 th:utext=\"${messageSecondary}\"&gt;Secondary&lt;\/h4&gt;\r\n \r\n                &lt;a class=\"btn btn-danger\" href=\"\/logout\"&gt;Log Out&lt;\/a&gt;\r\n                &lt;a class=\"btn btn-success\" href=\"\/\"&gt;Go Home&lt;\/a&gt;\r\n                &lt;a class=\"btn btn-warning\" th:href=\"@{${crossLink}}\"&gt;SSO: Jump to Other Site&lt;\/a&gt;\r\n            &lt;\/div&gt;\r\n        &lt;\/div&gt;\r\n    &lt;\/div&gt;\r\n \r\n    &lt;\/body&gt;\r\n&lt;\/html&gt;<\/pre>\n<p>There are two interesting lines here, from the perspective of interacting with ID Site.<\/p>\n<pre class=\"brush:bash\">&lt;h1 th:inline=\"text\"&gt;Hey, [[${account.fullName}]]&lt;\/h1&gt;<\/pre>\n<p>This line accesses the <code>fullName<\/code> property of the <code>Account<\/code> that is automatically set in the model passed in to the template.<\/p>\n<pre class=\"brush:bash\">&lt;a class=\"btn btn-danger\" href=\"\/logout\"&gt;Log Out&lt;\/a&gt;<\/pre>\n<p>The <code>\/logout<\/code> endpoint is automatically handled by IDSite and destroys the existing session.<\/p>\n<h3>Fire Up Your Webapp and Try It Out<\/h3>\n<p>Start up the app as before:<\/p>\n<pre class=\"brush:bash\">gradle clean build\r\nSTORMPATH_APPLICATION_HREF=https:\/\/api.stormpath.com\/v1\/applications\/6bHOGj63WM8cfC2nhD3Pki \\\r\n  java -jar build\/libs\/idsite_demo-0.1.0.jar<\/pre>\n<p>Since we don\u2019t yet have any users defined in our Stormpath directory, let\u2019s create a new user and then make sure we can log in and log out as that user.<\/p>\n<p>first, browse to the front door: <code>http:\/\/localhost:8080<\/code><\/p>\n<p><a href=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/restricted_home.png\"><img decoding=\"async\" class=\"aligncenter wp-image-60713\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/restricted_home.png\" alt=\"restricted_home\" width=\"860\" height=\"521\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/restricted_home.png 2164w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/restricted_home-300x182.png 300w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/restricted_home-768x466.png 768w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/restricted_home-1024x621.png 1024w\" sizes=\"(max-width: 860px) 100vw, 860px\" \/><\/a><\/p>\n<p>Click the friendly green button.<\/p>\n<p><a href=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/id_site_login.png\"><img decoding=\"async\" class=\"aligncenter wp-image-60712\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/id_site_login.png\" alt=\"id_site_login\" width=\"860\" height=\"534\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/id_site_login.png 1304w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/id_site_login-300x186.png 300w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/id_site_login-768x477.png 768w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/id_site_login-1024x636.png 1024w\" sizes=\"(max-width: 860px) 100vw, 860px\" \/><\/a><\/p>\n<p>Click the <code>Create an Account<\/code> link.<\/p>\n<p><a href=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/create_account.png\"><img decoding=\"async\" class=\"aligncenter wp-image-60714\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/create_account.png\" alt=\"create_account\" width=\"860\" height=\"521\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/create_account.png 2152w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/create_account-300x182.png 300w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/create_account-768x465.png 768w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/create_account-1024x620.png 1024w\" sizes=\"(max-width: 860px) 100vw, 860px\" \/><\/a><\/p>\n<p>Click the friendly green button.<\/p>\n<p><a href=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/restricted.png\"><img decoding=\"async\" class=\"aligncenter wp-image-60715\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/restricted.png\" alt=\"restricted\" width=\"860\" height=\"524\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/restricted.png 2158w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/restricted-300x183.png 300w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/restricted-768x468.png 768w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/restricted-1024x624.png 1024w\" sizes=\"(max-width: 860px) 100vw, 860px\" \/><\/a><\/p>\n<p>Huzzah! We\u2019re in!<\/p>\n<p>If you click the green button now, you will be brought back to the home page. If you then click the green button on the home page, you will go directly to the restricted page. You will not see the login form again. This is because you have established a valid session.<\/p>\n<p><a href=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/loggedin.gif\"><img decoding=\"async\" class=\"aligncenter wp-image-60716\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/loggedin.gif\" alt=\"loggedin\" width=\"860\" height=\"520\" \/><\/a><\/p>\n<p>If you click the red button, you will be logged out and redirected to the home page. Clicking the green button brings you to the login form once again as you have trashed your session.<\/p>\n<p>You may notice that after we created our account, we were immediately logged in and sent to the restricted page. You can slow this down by requiring email verification in your Stormpath admin console as part of the account creation process.<\/p>\n<p><strong>Note<\/strong>: There is a known issue whereby you cannot be logged into the Stormpath Admin Dashboard and authenticate using ID Site in the same session. We are working on resolving this issue ASAP. It would never affect your users as they would never be in your Stormpath Admin Dashboard. For now, use a separate browser profile or separate browser instance when using the Stormpath Admin Dashbaord.<\/p>\n<h2>Single Sign-On with Heroku in 5 Minutes<\/h2>\n<p>This section uses the <a href=\"https:\/\/github.com\/stormpath\/spring-boot-idsite-sso-demo\/tree\/SpringBootStormpathIDSite\">SpringBootStormpathIDSite<\/a> tag in the github repository.<\/p>\n<p><a href=\"https:\/\/signup.heroku.com\/deploy?redirect-url=https%3A%2F%2Fdashboard.heroku.com%2Fnew%3Fbutton-url%3Dhttps%253A%252F%252Fstormpath.com%252Fblog%252Fspring-boot_id-site_heroku%26template%3Dhttps%253A%252F%252Fgithub.com%252Fstormpath%252Fspring-boot-idsite-sso-demo%252Ftree%252FSpringBootStormpathIDSite\"><img decoding=\"async\" style=\"border:none\" class=\"aligncenter size-full wp-image-60700\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/button.png\" alt=\"button\" width=\"147\" height=\"32\" \/><\/a><\/p>\n<p><strong>Note<\/strong>: You can use the Heroku Deploy button above to deploy two different Heroku Apps if you want to test out SSO without deploying yourself.<\/p>\n<p>Phew! Home stretch! So, what\u2019s this SSO I keep hearing so much about? With the foundation we\u2019ve built, we are now in a position to deploy multiple instances of this web app to Heroku. So What? I\u2019ll tell you \u201cSo What!\u201d<\/p>\n<p>While it\u2019s a novelty that we can deploy multiple instances of the web app, what really gives it power is ID Site\u2019s Single Sign-On capability. By the end of this section you will see that by logging in to one instance of the webapp, you can browse to the restricted page of another instance of the web app<em>without<\/em> having to log in again.<\/p>\n<p>First, we need to add a file so Heroku knows how to launch our app. It\u2019s a one-liner called <code>Procfile<\/code>:<\/p>\n<pre class=\"brush:bash\">web: java $JAVA_OPTS -Dserver.port=$PORT -jar target\/*.jar<\/pre>\n<p>Notice the <code>bash<\/code> style variable: <code>$PORT<\/code>. This is automatically populated by Heroku and does not need to be explicitly set by us.<\/p>\n<p>Let\u2019s setup and deploy one Heroku app and make sure it all works<\/p>\n<pre class=\"brush:bash\">heroku apps:create idsite-demo-app1 --remote idsite-demo-app1<\/pre>\n<p>Notice the <code>--remote<\/code> on the end of the command. Heroku automatically adds a <code>git<\/code> remote to your local repository in order to be able to deploy your app. By default, this remote will be named <code>heroku<\/code>. Since we will be deploying multiple instances of the app, we want different remote names.<\/p>\n<p>Now that we\u2019ve created the app, we need to set some config parameters. This is part of the secret sauce that allows us to deploy the same codebase, but link the web app to different Stormpath Applications.<\/p>\n<pre class=\"brush:bash\">heroku config:set \\\r\n  STORMPATH_API_KEY_ID=&lt;your api key id&gt; \\\r\n  STORMPATH_API_KEY_SECRET=&lt;your api key secret&gt; \\\r\n  STORMPATH_APPLICATION_HREF=&lt;your app href&gt; \\\r\n  STORMPATH_SSO_CROSS_LINK=https:\/\/idsite-demo-app2.herokuapp.com\/restricted\/secret \\\r\n  STORMPATH_SSO_MESSAGE_PRIMARY=\"The secret is that chocolate is delicious\"'!' \\\r\n  STORMPATH_SSO_MESSAGE_SECONDARY=\"Yummy\"'!' \\\r\n--app idsite-demo-app1\r\n<\/pre>\n<p>This assumes that you have a second app setup called <code>idsite-demo-app2<\/code> deployed to Heroku. The<code>STORMPATH_SSO_CROSS_LINK<\/code> is used on this app\u2019s restricted page to link to the other app. With everything setup correctly, you will not have to log in again. That\u2019s the sweet power of single sign-on!<\/p>\n<p>Remember I said earlier one of the benefits of how Stormpath configures itself is that you are not required to embed sensitive api key information in your code? Here\u2019s where it all comes together. In the above command, we are setting environment variables for our Heroku instance. The Stormpath SDK automatically checks for the presense of <code>STORMPATH_API_KEY_ID<\/code>, <code>STORMPATH_API_KEY_SECRET<\/code> and<code>STORMPATH_APPLICATION_HREF<\/code> environment variables. If present, the SDK will automatically use the values in those environment variables when interacting with the API. It\u2019s what connects our Spring Boot web app to the right Stormpath Application.<\/p>\n<p>Ok. The stage is set. Let\u2019s deploy our app!<\/p>\n<pre class=\"brush:bash\">git push idsite-demo-app1 master<\/pre>\n<p>This generates a ton of output, but let\u2019s look at some of the highlights:<\/p>\n<pre class=\"brush:bash; wrap-lines:false\">remote: Compressing source files... done.        \r\nremote: Building source:        \r\n \r\n...\r\n \r\nremote:        [INFO]                                                                                 \r\nremote:        [INFO] ------------------------------------------------------------------------        \r\nremote:        [INFO] Building demo 0.0.1-SNAPSHOT        \r\nremote:        [INFO] ------------------------------------------------------------------------        \r\n \r\n...\r\n \r\nremote:        [INFO] Installing \/tmp\/build_a7299c4194f003c6e3730e568a540e82\/target\/demo-0.0.1-SNAPSHOT.jar to \/app\/tmp\/cache\/.m2\/repository\/com\/stormpath\/idsite_demo\/demo\/0.0.1-SNAPSHOT\/demo-0.0.1-SNAPSHOT.jar        \r\n \r\nremote:        [INFO] ------------------------------------------------------------------------        \r\nremote:        [INFO] BUILD SUCCESS        \r\nremote:        [INFO] ------------------------------------------------------------------------        \r\n \r\n...\r\n \r\nremote: -----&gt; Discovering process types        \r\nremote:        Procfile declares types -&gt; web        \r\nremote: \r\nremote: -----&gt; Compressing... done, 63.6MB        \r\nremote: -----&gt; Launching... done, v6        \r\nremote:        https:\/\/idsite-demo-app1.herokuapp.com\/ deployed to Heroku        \r\nremote: \r\nremote: Verifying deploy.... done.        \r\nTo https:\/\/git.heroku.com\/idsite-demo-app1.git\r\n * [new branch]      master -&gt; master\r\n<\/pre>\n<p>Toward the bottom, Heroku is discovering the process type based on our <code>Procfile<\/code>. In this case, it\u2019s<code>web<\/code>.<\/p>\n<p>Last bit of housekeeping for our first app is to configure ID Site to accept connections from it and to redirect to it. Jump back over to your admin dashboard for ID Site and add <code>https:\/\/idsite-demo-app1.herokuapp.com<\/code> to the list of Authorized Javascript Origin URLs and add <code>https:\/\/idsite-demo-app1.herokuapp.com\/<\/code> and <code>https:\/\/idsite-demo-app1.herokuapp.com\/idSiteResult<\/code> to the list of Authorized Redirect URLs.<\/p>\n<p><a href=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/id_site_3.png\"><img decoding=\"async\" class=\"aligncenter wp-image-60717\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/id_site_3.png\" alt=\"id_site_3\" width=\"860\" height=\"524\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/id_site_3.png 2156w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/id_site_3-300x183.png 300w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/id_site_3-768x468.png 768w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/id_site_3-1024x624.png 1024w\" sizes=\"(max-width: 860px) 100vw, 860px\" \/><\/a><\/p>\n<p>Make sure you click the <code>Save<\/code> button at the bottom of the screen.<\/p>\n<p>And, <a href=\"https:\/\/idsite-demo-app1.herokuapp.com\/\">https:\/\/idsite-demo-app1.herokuapp.com\/<\/a> is ready to go! Check it out. Create an account. Log in and log out. Have fun with it.<\/p>\n<p>We\u2019ve now arrived at the gates of the SSO promised land. Here\u2019s all that\u2019s left to do:<\/p>\n<ul>\n<li>Create another Stormpath Application<\/li>\n<li>Create another Heroku Application<\/li>\n<li>Set the configuration of the new Heroku Application<\/li>\n<li>Deploy our Spring Boot app to the new Heroku Application<\/li>\n<li>Update our ID Site to include the new URLs for authorized origin and redirect<\/li>\n<\/ul>\n<p>We are just rinsing and repeating what we did before.<\/p>\n<p>Let\u2019s go create our new Stormpath Application:<\/p>\n<p><a href=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/new_application_2.png\"><img decoding=\"async\" class=\"aligncenter wp-image-60718\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/new_application_2.png\" alt=\"new_application_2\" width=\"860\" height=\"504\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/new_application_2.png 1439w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/new_application_2-300x176.png 300w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/new_application_2-768x450.png 768w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/new_application_2-1024x600.png 1024w\" sizes=\"(max-width: 860px) 100vw, 860px\" \/><\/a><\/p>\n<p>Notice that we are mapping the same Account Store for this new application.<\/p>\n<p>Time to create a new Heroku app<\/p>\n<pre class=\"brush:bash\">heroku apps:create idsite-demo-app2 --remote idsite-demo-app2<\/pre>\n<p>And, configure it:<\/p>\n<pre class=\"brush:bash\">heroku config:set \\\r\n  STORMPATH_API_KEY_ID=&lt;your api key id&gt; \\\r\n  STORMPATH_API_KEY_SECRET=&lt;your api key secret&gt; \\\r\n  STORMPATH_APPLICATION_HREF=&lt;your app href&gt; \\\r\n  STORMPATH_SSO_CROSS_LINK=https:\/\/idsite-demo-app1.herokuapp.com\/restricted\/secret \\\r\n  STORMPATH_SSO_MESSAGE_PRIMARY=\"The secret is that ice cream is delicious\"'!' \\\r\n  STORMPATH_SSO_MESSAGE_SECONDARY=\"Yummy\"'!' \\\r\n--app idsite-demo-app2<\/pre>\n<p>Make sure you use the full URL of the newly created Stormpath Application.<\/p>\n<p>Deploy time:<\/p>\n<pre class=\"brush:bash\">git push idsite-demo-app2 master<\/pre>\n<p>Finally, ID Site URLs update:<\/p>\n<p><a href=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/id_site_4.png\"><img decoding=\"async\" class=\"aligncenter wp-image-60719\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/id_site_4.png\" alt=\"id_site_4\" width=\"860\" height=\"523\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/id_site_4.png 2160w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/id_site_4-300x183.png 300w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/id_site_4-768x467.png 768w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/id_site_4-1024x623.png 1024w\" sizes=\"(max-width: 860px) 100vw, 860px\" \/><\/a><\/p>\n<p>You can now check the box on your ToDo list that says: build and deploy an SSO application. You\u2019ve done it!<\/p>\n<p><a href=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/sso.gif\"><img decoding=\"async\" class=\"aligncenter wp-image-60720\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/10\/sso.gif\" alt=\"sso\" width=\"860\" height=\"520\" \/><\/a><\/p>\n<p>You can log in to <a href=\"https:\/\/idsite-demo-app1.herokuapp.com\/\">https:\/\/idsite-demo-app1.herokuapp.com<\/a>. Then, you can jump directly over to\u00a0<a href=\"https:\/\/idsite-demo-app2.herokuapp.com\/restricted\/secret\">https:\/\/idsite-demo-app2.herokuapp.com\/restricted\/secret<\/a> and you will not have to login again!<\/p>\n<h2>Happy SSOing!<\/h2>\n<p>In this post, you\u2019ve created a Spring Boot web app that enables Single Sign-On with Stormpath\u2019s ID Site service. Stormpath hosts the login form and all the other links and forms associated with creating a new user and resetting your password.<\/p>\n<p>With a small amount of code in one Controller, you can authenticate and authorize users for your app. And you deployed it quickly with Heroku. I\u2019d love to hear about your experience in working with the examples in this post.<\/p>\n<p>If you\u2019re interested in using more features of Stormpath in Spring Boot, here\u2019s our <a href=\"http:\/\/docs.stormpath.com\/java\/spring-boot-web\/quickstart.html?utm_source=java-code-geeks&amp;utm_medium=post&amp;utm_content=spring-boot-id-site&amp;utm_campaign=spring-java-2016\">Spring Boot Webapp Sample Quickstart<\/a><\/p>\n<p>Feel free to drop a line over to <a title=\"Stormpath Support Email\" href=\"mailto:support@stormpath.com\">email<\/a> or to <a title=\"Micah Silverman\" href=\"mailto:micah@stormpath.com\">me<\/a> personally anytime.<\/p>\n<p><span style=\"font-size: 20px;\">Building Identity Management, including authentication and authorization? Try Stormpath! Our REST API and <a href=\"https:\/\/docs.stormpath.com\/java\/?utm_source=java-code-geeks&#038;utm_medium=post&#038;utm_content=spring-boot-id-site&#038;utm_campaign=spring-java-2016\">robust Java SDK support<\/a> can eliminate your security risk and can be implemented in minutes. <a href=\"https:\/\/api.stormpath.com\/register?utm_source=java-code-geeks&#038;utm_medium=post&#038;utm_content=spring-boot-id-site&#038;utm_campaign=spring-java-2016\">Sign up<\/a>, and never build auth again!<\/span><\/p>\n<p><a href=\"https:\/\/api.stormpath.com\/register?utm_source=java-code-geeks&#038;utm_medium=post&#038;utm_content=spring-boot-id-site&#038;utm_campaign=spring-java-2016\"><img decoding=\"async\" style=\"border:none\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2016\/09\/button-sign-up-now.png\" alt=\"button-sign-up-now\" width=\"180\" height=\"51\" class=\"aligncenter size-full wp-image-60632\" \/><\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Building Identity Management, including authentication and authorization? Try Stormpath! Our REST API and robust Java SDK support can eliminate your security risk and can be implemented in minutes. Sign up, and never build auth again! Massive Update The code I originally wrote for this post is more suited to non-Spring Boot environments. Stormpath\u2019s existing Spring &hellip;<\/p>\n","protected":false},"author":1062,"featured_media":240,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[222,30,854],"class_list":["post-60699","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-enterprise-java","tag-heroku","tag-spring","tag-spring-boot"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Single Sign-on for Java in 20 Minutes with Spring Boot and Heroku - Java Code Geeks<\/title>\n<meta name=\"description\" content=\"Building Identity Management, including authentication and authorization? Try Stormpath! Our REST API and robust Java SDK support can eliminate your\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.javacodegeeks.com\/2016\/10\/single-sign-java-20-minutes-spring-boot-heroku.html\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Single Sign-on for Java in 20 Minutes with Spring Boot and Heroku - Java Code Geeks\" \/>\n<meta property=\"og:description\" content=\"Building Identity Management, including authentication and authorization? Try Stormpath! Our REST API and robust Java SDK support can eliminate your\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.javacodegeeks.com\/2016\/10\/single-sign-java-20-minutes-spring-boot-heroku.html\" \/>\n<meta property=\"og:site_name\" content=\"Java Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/javacodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2016-10-17T06:48:45+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2016-10-24T08:04:09+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Micah Silverman\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:site\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Micah Silverman\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"24 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2016\\\/10\\\/single-sign-java-20-minutes-spring-boot-heroku.html#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2016\\\/10\\\/single-sign-java-20-minutes-spring-boot-heroku.html\"},\"author\":{\"name\":\"Micah Silverman\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/fd211fe0d3a9791d30dd0ca5276d9660\"},\"headline\":\"Single Sign-on for Java in 20 Minutes with Spring Boot and Heroku\",\"datePublished\":\"2016-10-17T06:48:45+00:00\",\"dateModified\":\"2016-10-24T08:04:09+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2016\\\/10\\\/single-sign-java-20-minutes-spring-boot-heroku.html\"},\"wordCount\":3627,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2016\\\/10\\\/single-sign-java-20-minutes-spring-boot-heroku.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/spring-logo.jpg\",\"keywords\":[\"Heroku\",\"Spring\",\"Spring Boot\"],\"articleSection\":[\"Enterprise Java\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2016\\\/10\\\/single-sign-java-20-minutes-spring-boot-heroku.html#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2016\\\/10\\\/single-sign-java-20-minutes-spring-boot-heroku.html\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2016\\\/10\\\/single-sign-java-20-minutes-spring-boot-heroku.html\",\"name\":\"Single Sign-on for Java in 20 Minutes with Spring Boot and Heroku - Java Code Geeks\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2016\\\/10\\\/single-sign-java-20-minutes-spring-boot-heroku.html#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2016\\\/10\\\/single-sign-java-20-minutes-spring-boot-heroku.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/spring-logo.jpg\",\"datePublished\":\"2016-10-17T06:48:45+00:00\",\"dateModified\":\"2016-10-24T08:04:09+00:00\",\"description\":\"Building Identity Management, including authentication and authorization? Try Stormpath! Our REST API and robust Java SDK support can eliminate your\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2016\\\/10\\\/single-sign-java-20-minutes-spring-boot-heroku.html#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2016\\\/10\\\/single-sign-java-20-minutes-spring-boot-heroku.html\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2016\\\/10\\\/single-sign-java-20-minutes-spring-boot-heroku.html#primaryimage\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/spring-logo.jpg\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/spring-logo.jpg\",\"width\":150,\"height\":150,\"caption\":\"spring-interview-questions-answers\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2016\\\/10\\\/single-sign-java-20-minutes-spring-boot-heroku.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Enterprise Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\\\/enterprise-java\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"Single Sign-on for Java in 20 Minutes with Spring Boot and Heroku\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"name\":\"Java Code Geeks\",\"description\":\"Java Developers Resource Center\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"alternateName\":\"JCG\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.javacodegeeks.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/javacodegeeks\",\"https:\\\/\\\/x.com\\\/javacodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/fd211fe0d3a9791d30dd0ca5276d9660\",\"name\":\"Micah Silverman\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/fdd31b256ed406e9651be5c9f709a208535846dc978cc1b1211f9ca2473709de?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/fdd31b256ed406e9651be5c9f709a208535846dc978cc1b1211f9ca2473709de?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/fdd31b256ed406e9651be5c9f709a208535846dc978cc1b1211f9ca2473709de?s=96&d=mm&r=g\",\"caption\":\"Micah Silverman\"},\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/author\\\/micah-silverman\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Single Sign-on for Java in 20 Minutes with Spring Boot and Heroku - Java Code Geeks","description":"Building Identity Management, including authentication and authorization? Try Stormpath! Our REST API and robust Java SDK support can eliminate your","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.javacodegeeks.com\/2016\/10\/single-sign-java-20-minutes-spring-boot-heroku.html","og_locale":"en_US","og_type":"article","og_title":"Single Sign-on for Java in 20 Minutes with Spring Boot and Heroku - Java Code Geeks","og_description":"Building Identity Management, including authentication and authorization? Try Stormpath! Our REST API and robust Java SDK support can eliminate your","og_url":"https:\/\/www.javacodegeeks.com\/2016\/10\/single-sign-java-20-minutes-spring-boot-heroku.html","og_site_name":"Java Code Geeks","article_publisher":"https:\/\/www.facebook.com\/javacodegeeks","article_published_time":"2016-10-17T06:48:45+00:00","article_modified_time":"2016-10-24T08:04:09+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","type":"image\/jpeg"}],"author":"Micah Silverman","twitter_card":"summary_large_image","twitter_creator":"@javacodegeeks","twitter_site":"@javacodegeeks","twitter_misc":{"Written by":"Micah Silverman","Est. reading time":"24 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.javacodegeeks.com\/2016\/10\/single-sign-java-20-minutes-spring-boot-heroku.html#article","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/2016\/10\/single-sign-java-20-minutes-spring-boot-heroku.html"},"author":{"name":"Micah Silverman","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/fd211fe0d3a9791d30dd0ca5276d9660"},"headline":"Single Sign-on for Java in 20 Minutes with Spring Boot and Heroku","datePublished":"2016-10-17T06:48:45+00:00","dateModified":"2016-10-24T08:04:09+00:00","mainEntityOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2016\/10\/single-sign-java-20-minutes-spring-boot-heroku.html"},"wordCount":3627,"commentCount":0,"publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2016\/10\/single-sign-java-20-minutes-spring-boot-heroku.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","keywords":["Heroku","Spring","Spring Boot"],"articleSection":["Enterprise Java"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.javacodegeeks.com\/2016\/10\/single-sign-java-20-minutes-spring-boot-heroku.html#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.javacodegeeks.com\/2016\/10\/single-sign-java-20-minutes-spring-boot-heroku.html","url":"https:\/\/www.javacodegeeks.com\/2016\/10\/single-sign-java-20-minutes-spring-boot-heroku.html","name":"Single Sign-on for Java in 20 Minutes with Spring Boot and Heroku - Java Code Geeks","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2016\/10\/single-sign-java-20-minutes-spring-boot-heroku.html#primaryimage"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2016\/10\/single-sign-java-20-minutes-spring-boot-heroku.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","datePublished":"2016-10-17T06:48:45+00:00","dateModified":"2016-10-24T08:04:09+00:00","description":"Building Identity Management, including authentication and authorization? Try Stormpath! Our REST API and robust Java SDK support can eliminate your","breadcrumb":{"@id":"https:\/\/www.javacodegeeks.com\/2016\/10\/single-sign-java-20-minutes-spring-boot-heroku.html#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.javacodegeeks.com\/2016\/10\/single-sign-java-20-minutes-spring-boot-heroku.html"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/2016\/10\/single-sign-java-20-minutes-spring-boot-heroku.html#primaryimage","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","width":150,"height":150,"caption":"spring-interview-questions-answers"},{"@type":"BreadcrumbList","@id":"https:\/\/www.javacodegeeks.com\/2016\/10\/single-sign-java-20-minutes-spring-boot-heroku.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.javacodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Java","item":"https:\/\/www.javacodegeeks.com\/category\/java"},{"@type":"ListItem","position":3,"name":"Enterprise Java","item":"https:\/\/www.javacodegeeks.com\/category\/java\/enterprise-java"},{"@type":"ListItem","position":4,"name":"Single Sign-on for Java in 20 Minutes with Spring Boot and Heroku"}]},{"@type":"WebSite","@id":"https:\/\/www.javacodegeeks.com\/#website","url":"https:\/\/www.javacodegeeks.com\/","name":"Java Code Geeks","description":"Java Developers Resource Center","publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"alternateName":"JCG","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.javacodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.javacodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.javacodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/javacodegeeks","https:\/\/x.com\/javacodegeeks"]},{"@type":"Person","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/fd211fe0d3a9791d30dd0ca5276d9660","name":"Micah Silverman","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/fdd31b256ed406e9651be5c9f709a208535846dc978cc1b1211f9ca2473709de?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/fdd31b256ed406e9651be5c9f709a208535846dc978cc1b1211f9ca2473709de?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/fdd31b256ed406e9651be5c9f709a208535846dc978cc1b1211f9ca2473709de?s=96&d=mm&r=g","caption":"Micah Silverman"},"url":"https:\/\/www.javacodegeeks.com\/author\/micah-silverman"}]}},"_links":{"self":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/60699","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/users\/1062"}],"replies":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/comments?post=60699"}],"version-history":[{"count":0,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/60699\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media\/240"}],"wp:attachment":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media?parent=60699"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/categories?post=60699"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/tags?post=60699"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}