{"id":87537,"date":"2019-02-04T09:29:50","date_gmt":"2019-02-04T07:29:50","guid":{"rendered":"http:\/\/www.javacodegeeks.com\/?p=87537"},"modified":"2019-02-11T10:08:03","modified_gmt":"2019-02-11T08:08:03","slug":"build-web-app-spring-boot-spring-security","status":"publish","type":"post","link":"https:\/\/www.javacodegeeks.com\/2019\/02\/build-web-app-spring-boot-spring-security.html","title":{"rendered":"Build a Web App with Spring Boot and Spring Security in 15 Minutes"},"content":{"rendered":"<p><span style=\"font-size: 20px;\"><b>\u201cI love writing authentication and authorization code.\u201d ~ No Java Developer Ever.<\/b> Tired of building the same login screens over and over? <a href=\"https:\/\/developer.okta.com\/signup?utm_campaign=text_website_all_multiple_dev_ciam_webapp-spring-boot-security-15-min_null&amp;utm_source=jcg&amp;utm_medium=cpc\">Try the Okta API for hosted authentication, authorization, and multi-factor auth.<\/a><\/span><\/p>\n<p>Developers know that securing web apps can be a pain. Doing it right is tough. The worst part is that \u201cright\u201d is a moving target. Security protocols change. Vulnerabilities are found in dependencies and patches are released. Tons of often complex boilerplate code has to be generated. The software-as-service paradigm has proliferated over the last decade, and while I love reinventing the wheel as much as the next developer (because, clearly, I\u2019m gonna write it better than the yahoo&nbsp;<em>they<\/em>&nbsp;hired), security is an area where I\u2019m happy to offload this work to specialists. Enter Okta.<\/p>\n<p>In this tutorial, you\u2019re going to use Spring Boot to build a simple web application with a user registration system and a login system. It will have the following features:<\/p>\n<ul class=\"wp-block-list\">\n<li>Login and registration pages<\/li>\n<li>Password reset workflows<\/li>\n<li>Restricting access according to group membership<\/li>\n<\/ul>\n<h2 class=\"wp-block-heading\">Download the Spring Boot Web App Example Project<\/h2>\n<p>The first thing you\u2019re going to need is a free Okta account. If you don\u2019t already have one, head over to&nbsp;<a href=\"https:\/\/developer.okta.com\/?utm_campaign=text_website_all_multiple_dev_ciam_webapp-spring-boot-security-15-min_null&amp;utm_source=jcg&amp;utm_medium=cpc\">developer.okta.com<\/a>&nbsp;and sign up!<\/p>\n<p>The next thing will be to download the example project for this tutorial&nbsp;<a href=\"https:\/\/github.com\/oktadeveloper\/okta-spring-simple-app-example\">from GitHub<\/a>.<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:bash\">git clone https:\/\/github.com\/oktadeveloper\/okta-spring-simple-app-example.git spring-app<\/pre>\n<p>This project uses Gradle, as the build tool, and the Thymeleaf templating system.<\/p>\n<h2 class=\"wp-block-heading\">Run the Initial Web App<\/h2>\n<p>Once you have downloaded the example code from the GitHub repository, checkout out the&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">Start<\/code>&nbsp;tag using the following git command:&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">git checkout tags\/Start<\/code>.<\/p>\n<p>The app at this point it not protected at all. There is no authorization or authentication enabled (even though the necessary dependencies are included in the&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">build.gradle<\/code>&nbsp;file). Go ahead and run the example by opening a terminal and, from the project root directory, running the command&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">.\/gradlew bootRun<\/code>&nbsp;(The&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">bootRun<\/code>&nbsp;command is a task provided by the Gradle Spring Boot plugin, added to the&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">build.gradle<\/code>&nbsp;file in the buildscript section at the top of the file).<\/p>\n<p>Navigate to&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">http:\/\/localhost:8080<\/code>&nbsp;in your favorite browser, and you should see this:<\/p>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img decoding=\"async\" width=\"603\" height=\"375\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/01\/1-1.png\" alt=\"Web App\" class=\"wp-image-87540\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/01\/1-1.png 603w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/01\/1-1-300x187.png 300w\" sizes=\"(max-width: 603px) 100vw, 603px\" \/><\/figure>\n<\/div>\n<p>And if you click on the \u201cRestricted\u201d button:<\/p>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img decoding=\"async\" width=\"566\" height=\"397\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/01\/2-2.png\" alt=\"Web App\" class=\"wp-image-87541\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/01\/2-2.png 566w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/01\/2-2-300x210.png 300w\" sizes=\"(max-width: 566px) 100vw, 566px\" \/><\/figure>\n<\/div>\n<h2 class=\"wp-block-heading\">Add Project Dependencies for Your Spring Boot + Spring Security Web App<\/h2>\n<p>The project dependencies are defined in the&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">build.gradle<\/code>&nbsp;file (see below). There\u2019s a lot going on in this file, and this tutorial isn\u2019t going to try and explain the Gradle build system to you. Feel free to check out&nbsp;<a href=\"https:\/\/docs.gradle.org\/current\/userguide\/userguide.html\">their documentation<\/a>. I just want to point out a few things.<\/p>\n<p>First off, notice that we\u2019re including the&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">okta-spring-boot-starter<\/code>. This project greatly simplifies integrating Okta with your Spring Boot application. It\u2019s entirely possible to use Okta and Spring Boot without this starter. In fact, up to the point where Groups and Roles are introduced, the differences are minor (mostly involve&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">application.yml<\/code>&nbsp;changes). However, once you start to trying to integrate Groups and Roles, the Okta Spring Boot Starter saves a lot of coding. If you\u2019d like to look a little deeper, take a look at the&nbsp;<a href=\"https:\/\/github.com\/okta\/okta-spring-boot\">Okta Spring Boot Starter GitHub project<\/a>.<\/p>\n<p>The rest of the dependencies deal with Spring and Spring Boot. You\u2019ll notice none of the&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">org.springframework.boot<\/code>dependencies have version numbers. This is because of some behind-the-scenes magic being done by the Spring&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">io.spring.dependency-management<\/code>&nbsp;Gradle plugin. The Spring Boot Version is set by the build script property&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">springBootVersion<\/code>&nbsp;near the top of the&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">build.gradle<\/code>&nbsp;file. Based on this version number, the Spring dependency management plugin decides what versions of dependencies to include.<\/p>\n<p>We\u2019re also bringing in the&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">org.springframework.boot<\/code>&nbsp;Gradle plugin, which adds the&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">bootRun<\/code>&nbsp;task that we\u2019ll use to run the app.<\/p>\n<ul class=\"wp-block-list\">\n<li><code class=\"highlighter-rouge\" style=\"font-size: 13px;\">spring-boot-starter-security<\/code>&nbsp;and&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">spring-boot-starter-web<\/code>&nbsp;are core Spring Boot dependencies.<\/li>\n<li><code class=\"highlighter-rouge\" style=\"font-size: 13px;\">spring-security-oauth2-autoconfigure<\/code>&nbsp;is required to use the&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">@EnableOAuth2Sso<\/code>&nbsp;annotation that we use to hook OAuth and Single Sign-On into our app.<\/li>\n<li><code class=\"highlighter-rouge\" style=\"font-size: 13px;\">spring-boot-starter-thymeleaf<\/code>&nbsp;and&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">thymeleaf-extras-springsecurity4<\/code>&nbsp;bring in the Thymeleaf templating system and integrate it with Spring Security.<\/li>\n<\/ul>\n<pre class=\"wp-block-preformatted gutter: false;brush:js; wrap-lines:false\">buildscript {  \n   ext {  \n      springBootVersion = '2.0.5.RELEASE'  \n  }  \n   repositories {  \n      mavenCentral()  \n   }  \n   dependencies {  \n      classpath(\"org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}\")  \n   }  \n}  \n  \napply plugin: 'java'  \napply plugin: 'eclipse'  \napply plugin: 'org.springframework.boot'  \napply plugin: 'io.spring.dependency-management'  \n  \ngroup = 'com.okta.springboot'  \nversion = '0.0.1-SNAPSHOT'  \nsourceCompatibility = 1.8  \n  \nrepositories {  \n   mavenCentral()  \n}  \n  \ndependencies {  \n   compile('com.okta.spring:okta-spring-boot-starter:0.6.0')  \n   compile('org.springframework.boot:spring-boot-starter-security')  \n   compile('org.springframework.boot:spring-boot-starter-web')  \n   compile('org.springframework.boot:spring-boot-starter-thymeleaf')  \n   compile('org.thymeleaf.extras:thymeleaf-extras-springsecurity4')  \n   compile('org.springframework.security.oauth.boot:spring-security-oauth2-autoconfigure:2.0.5.RELEASE')  \n   testCompile('org.springframework.boot:spring-boot-starter-test')  \"\n   testCompile('org.springframework.security:spring-security-test')  \n}  \n  \n\/*  \n This is required to resolve a logging dependency conflict between the \n okta-spring-boot-starter and the various spring dependencies. \n *\/\nconfigurations.all {  \n    exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'  \n    exclude group: 'org.springframework.boot', module: 'logback-classic'  \n}\n<\/pre>\n<h2 class=\"wp-block-heading\">Understand Your Spring Boot App<\/h2>\n<p>The Java web application has only three class files and a few templates. Obviously Spring Boot is doing a lot of heavy hitting going on in the background, but what\u2019s going on in our class files?<\/p>\n<p>The application entry point is in the&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">SpringSimpleApplication<\/code>&nbsp;class:<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:java\">@SpringBootApplication  \npublic class SpringSimpleApplication {  \n     public static void main(String[] args) {  \n        SpringApplication.run(SpringSimpleApplication.class, args);  \n     }  \n}<\/pre>\n<p>Two important things are happening here that get things rolling: 1) we use the&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">@SpringBootApplication<\/code>&nbsp;annotation, and 2) our&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">main<\/code>&nbsp;method calls the&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">SpringApplication.run()<\/code>&nbsp;method. This is the entry point to the entire Spring\/Spring Boot system.<\/p>\n<p>The&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">SpringSecurityWebAppConfig<\/code>&nbsp;class is a way to use Java code to configure how Spring Boot handles web app security. Here we use the&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">HttpSecurity<\/code>&nbsp;object to remove authorization from all endpoints. By default, the Spring Boot behavior is the opposite: all endpoints require authorization.<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:java\">@Configuration  \npublic class SpringSecurityWebAppConfig extends WebSecurityConfigurerAdapter {  \n\n    @Override  \n    protected void configure(HttpSecurity http) throws Exception {\n        http.authorizeRequests().anyRequest().permitAll();          \n    }\n}\n<\/pre>\n<p>The&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">@Configuration<\/code>&nbsp;annotation tells Spring that we are using the class as a source of programmatic configuration, allowing us to override the&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">configure()<\/code>&nbsp;method.<\/p>\n<p>The last Java class,&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">SimpleAppController<\/code>, is our only controller object. Controllers in a Spring Boot web application are where URL requests are mapped to Java code. The&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">@Controller<\/code>&nbsp;annotation tells Spring that this class is a controller.<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:java\">@Controller  \nclass SimpleAppController {  \n  \n    @RequestMapping(\"\/\")  \n    String home() {  \n        return \"home\";  \n    }  \n  \n    @RequestMapping(\"\/restricted\")  \n    String restricted() {  \n        return \"restricted\";  \n    }  \n  \n}\n<\/pre>\n<p>Connections between class methods and URLs are made using the&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">@RequestMapping<\/code>&nbsp;annotation.<\/p>\n<p>We have two mappings:<\/p>\n<ol class=\"wp-block-list\">\n<li>\u201chome\u201d mapping<\/li>\n<li>\u201crestricted\u201d mapping<\/li>\n<\/ol>\n<p>Remember that initially nothing is actually \u201crestricted\u201d, so don\u2019t get confused by that. You\u2019ll lock that mapping down in a bit.<div style=\"display:inline-block; margin: 15px 0;\"> <div id=\"adngin-JavaCodeGeeks_incontent_video-0\" style=\"display:inline-block;\"><\/div> <\/div><\/p>\n<p>Also notice that the classes return a simple text string, but this is getting auto-magically turned into a full html file. This is part of the Thymeleaf dependency that is included in the&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">build.gradle<\/code>&nbsp;file. These strings are assumed to be template file names, which are by default paths in the&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">templates<\/code>&nbsp;directory on the classpath.<\/p>\n<p>Thus \u201chome\u201d is mapped to the&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">src\/main\/resources\/templates\/home.html<\/code>&nbsp;template file. When the web app is packaged in the the final jar, the entire resources folder is copied into the classpath, so that the&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">templates<\/code>&nbsp;directory is accessible at runtime.<\/p>\n<h2 class=\"wp-block-heading\">Set Up Okta for OAuth 2.0 Single Sign-On<\/h2>\n<p>Now you\u2019re going to set up authorization for our app. Okta makes this super easy. You should have already signed up for a free&nbsp;<a href=\"https:\/\/developer.okta.com\/?utm_campaign=text_website_all_multiple_dev_ciam_webapp-spring-boot-security-15-min_null&amp;utm_source=jcg&amp;utm_medium=cpc\">developer.okta.com<\/a>&nbsp;account. Now you\u2019re going to create an OpenID Connect (OIDC) application to use with OAuth 2.0 Single Sign-On (SSO).<\/p>\n<p>That might be a lot of jargon and acronyms, if you\u2019re not already familiar with them. Very simply,&nbsp;<a href=\"https:\/\/oauth.net\/2\/\">OAuth 2.0<\/a>&nbsp;is an industry standard for authorization &#8211; a standardized and tested method by which authorization servers and applications can communicate to facilitate user authorization.&nbsp;<a href=\"https:\/\/openid.net\/connect\/\">OpenID Connect<\/a>&nbsp;is a layer on top of OAuth 2.0 that standardizes and simplifies the authorization procedure as well as providing user authentication. Together they provide a proven way for an application to interact with a remote server that provides authentication and authorization services (such as Okta).<\/p>\n<p>To create an OIDC app, open your Okta developer dashboard. Click on the&nbsp;<strong>Applications<\/strong>&nbsp;top menu item, and then click on&nbsp;<strong>Add Application<\/strong>.<\/p>\n<p>You should see the following screen. Click on the icon for the&nbsp;<strong>Web<\/strong>&nbsp;option. Click&nbsp;<strong>Next<\/strong>.<\/p>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter is-resized\"><img decoding=\"async\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/01\/3-2-1024x638.png\" alt=\"Web App\" class=\"wp-image-87542\" width=\"820\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/01\/3-2-1024x638.png 1024w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/01\/3-2-300x187.png 300w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/01\/3-2-768x478.png 768w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/01\/3-2.png 1069w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n<\/div>\n<p>You need to update a few of the initial configuration options. First change the name to something more descriptive. I used \u201cOkta Spring Boot Simple Web App.\u201d Next update the&nbsp;<strong>Login redirect URIs<\/strong>&nbsp;to&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">http:\/\/localhost:8080\/login<\/code>. Click&nbsp;<strong>Done<\/strong>.<\/p>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img decoding=\"async\" width=\"775\" height=\"908\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/01\/4-1.png\" alt=\"Web App\" class=\"wp-image-87543\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/01\/4-1.png 775w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/01\/4-1-256x300.png 256w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/01\/4-1-768x900.png 768w\" sizes=\"(max-width: 775px) 100vw, 775px\" \/><\/figure>\n<\/div>\n<p>This will take you to the new application\u2019s general configuration tab. Scroll down and note the Client ID and Client secret. You\u2019ll need these later.<\/p>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img decoding=\"async\" width=\"793\" height=\"485\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/01\/5.png\" alt=\"Web App\" class=\"wp-image-87544\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/01\/5.png 793w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/01\/5-300x183.png 300w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/01\/5-768x470.png 768w\" sizes=\"(max-width: 793px) 100vw, 793px\" \/><\/figure>\n<\/div>\n<p>That\u2019s all you need to do to set up Okta for OAuth! Now let\u2019s return to the Spring Boot app and hook our new OIDC application into the Spring Boot application.<\/p>\n<h2 class=\"wp-block-heading\">Configure Your Spring Boot App for Single Sign-On (SSO)<\/h2>\n<p>Now you need to configure the Spring Boot app to interact with the Okta servers. This is super easy. We need to do two things:<\/p>\n<ol class=\"wp-block-list\">\n<li>Add the&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">@EnableOAuth2Sso<\/code>&nbsp;annotation<\/li>\n<li>Update the&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">application.yml<\/code>&nbsp;configuration<\/li>\n<\/ol>\n<p>First add the&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">@EnableOAuth2Sso<\/code>&nbsp;annotation to the&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">SpringSecurityWebAppConfig<\/code>&nbsp;class.<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:java\">@EnableOAuth2Sso  \n@Configuration  \npublic class WebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {  \n      \n    @Override  \n    protected void configure(HttpSecurity http) throws Exception {  \n        http.authorizeRequests().anyRequest().permitAll();          \n    }  \n}\n<\/pre>\n<p>The&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">@EnableOAuth2Sso<\/code>&nbsp;annotation does a TON of stuff. It\u2019s worth digging into to understand what\u2019s going on. You can check out&nbsp;<a href=\"https:\/\/docs.spring.io\/spring-security-oauth2-boot\/docs\/current\/api\/org\/springframework\/boot\/autoconfigure\/security\/oauth2\/client\/EnableOAuth2Sso.html\">Spring\u2019s docs on the annotation itself<\/a>, and their&nbsp;<a href=\"https:\/\/spring.io\/guides\/tutorials\/spring-boot-oauth2\/\">Spring Boot and OAuth2 tutorial<\/a>.<\/p>\n<p>One thing I want to point out (bc this has been bugging me a while and I just figured it out) is that you can put this annotation on other classes in the project. However, if you do, be aware that Spring is going to create a WebSecurityConfigurerAdapter and add it to the security chain. Since we\u2019re also creating a WebSecurityConfigurerAdapter, there will be two of them, and you\u2019ll get an error about conflicting chain orders. This is because both WebSecurityConfigurerAdapters will by default use the same chain order. You can resolve this error by adding an&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">@Order(101)<\/code>&nbsp;annotation to our customized class. However, even better is to add the&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">@EnableOAuth2Sso<\/code>&nbsp;annotation to our WebSecurityConfigurerAdapter class,&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">WebSecurityConfigurerAdapter<\/code>, and Spring will use that class instead of creating a duplicate one.<\/p>\n<p>The second change you need to make is update the&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">src\/main\/resources\/application.yml<\/code>&nbsp;file, filling in some Okta-specific configuration options for the OAuth SSO values take from our Okta OIDC application.<\/p>\n<p>You\u2019ll need to fill in your Client ID and Client secret from the application you created above. You\u2019ll also need to change the issuer URL so that it reflects your Okta preview URL, something like&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">dev-123456.oktapreview.com<\/code>.<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:bash\">server:  \n  port: 8080  \n  \nspring:  \n  resources: static-locations: \"classpath:\/static\/\"  \n                                   \nokta:  \n  oauth2: \n    issuer: https:\/\/{yourOktaDomain}\/oauth2\/default  \n    clientId: {yourClientId}  \n    clientSecret: {yourClientSecret}\n    rolesClaim: groups<\/pre>\n<h2 class=\"wp-block-heading\">Refine Our Permissions<\/h2>\n<p>Now you\u2019re going to want to update the&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">SpringSecurityWebAppConfig<\/code>&nbsp;class so that you have a public home page and a restricted \u201crestricted\u201d page. We do this by using Spring\u2019s fluent API for the HttpSecurity object.<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:java; wrap-lines:false\">import org.springframework.boot.autoconfigure.security.oauth2.client.EnableOAuth2Sso;\nimport org.springframework.context.annotation.Configuration;\nimport org.springframework.security.config.annotation.web.builders.HttpSecurity;\nimport org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;\n\n@EnableOAuth2Sso  \n@Configuration  \npublic class SpringSecurityWebAppConfig extends WebSecurityConfigurerAdapter {  \n      \n    @Override  \n    protected void configure(HttpSecurity http) throws Exception {  \n        http.authorizeRequests()  \n                .antMatchers(\"\/\").permitAll() \/\/ allow all at home page\n                .antMatchers(\"\/img\/**\").permitAll()  \/\/ allow all to access static images\n                .anyRequest().authenticated();  \/\/ authenticate everything else!\n    }  \n}\n<\/pre>\n<p>Restart your app and now you should be able to:<\/p>\n<ol class=\"wp-block-list\">\n<li>See the home page without authenticating<\/li>\n<li>NOT see the&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">\/restricted<\/code>&nbsp;page without authenticating<\/li>\n<li>Be able to authenticate using Okta Single Sign-On<\/li>\n<\/ol>\n<p>This point in the tutorial corresponds to the&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">OktaOAuthSSO<\/code>&nbsp;tag in the GitHub repository.<\/p>\n<h2 class=\"wp-block-heading\">Take a Look at the Thymeleaf Templates<\/h2>\n<p>The Thymeleaf templates are pretty self explanatory, on the whole, but I did want to point out a couple things. Thymeleaf templates are fully valid HTML5, which is nice. If you want to dig deeper, you can head over to&nbsp;<a href=\"https:\/\/www.thymeleaf.org\/index.html\">their website<\/a>&nbsp;and&nbsp;<a href=\"https:\/\/www.thymeleaf.org\/doc\/tutorials\/3.0\/usingthymeleaf.html\">their documentation<\/a>.<\/p>\n<p>What I wanted to point out is how the template brings in authentication information. To do this, we\u2019re using the&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">thymeleaf-extras-springsecurity<\/code>&nbsp;plugin. This is included in the&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">build.gradle<\/code>&nbsp;file with the following line:<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:bash\">compile (\"org.thymeleaf.extras:thymeleaf-extras-springsecurity4\")<\/pre>\n<p>And is included in the template file as an XML namespace attribute on the main&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\"><span class=\"nt\">&lt;html&gt;<\/span><\/code>&nbsp;tag.<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:bash\">xmlns:sec=\"http:\/\/www.thymeleaf.org\/thymeleaf-extras-springsecurity4\"<\/pre>\n<p>This plugin is what allows us to check if a user is authenticated using the&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">th:if<\/code>&nbsp;attribute with a custom SPEL expression (Spring Expression Language). It also allows us to insert authentication properties. Below you see a span&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">&lt;span th:text=\"${#authentication.name}\"&gt;&lt;\/span&gt;<\/code>&nbsp;that is used to insert the name of the authenticated user.<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:xml; wrap-lines:false\">&lt;html xmlns:th=\"http:\/\/www.thymeleaf.org\" xmlns:sec=\"http:\/\/www.thymeleaf.org\/thymeleaf-extras-springsecurity4\"&gt;  \n&lt;head&gt;  \n    &lt;!--\/*\/ &lt;th:block th:include=\"fragments\/head :: head\"\/&gt; \/*\/--&gt;  \n&lt;\/head&gt;  \n&lt;body&gt;  \n&lt;div class=\"container-fluid\"&gt;  \n    &lt;div class=\"row\"&gt;  \n        &lt;div class=\"box col-md-6 col-md-offset-3\"&gt;  \n            &lt;div class=\"okta-header\"&gt;  \n                &lt;img src=\"img\/logo.png\"\/&gt;  \n            &lt;\/div&gt;  \n  \n            &lt;!--\/* displayed if account IS NOT null, indicating that the user IS logged in *\/--&gt;  \n            &lt;div th:if=\"${#authorization.expression('isAuthenticated()')}\"&gt;  \n                &lt;h1 th:inline=\"text\"&gt;Hello, &lt;span th:text=\"${#authentication.name}\"&gt;&lt;\/span&gt;!&lt;\/h1&gt;  \n                &lt;a href=\"\/restricted\" class=\"btn btn-primary\"&gt;Restricted&lt;\/a&gt;  \n            &lt;\/div&gt;  \n  \n            &lt;!--\/* displayed if account IS null, indicating that the user IS NOT logged in *\/--&gt;  \n            &lt;div th:unless=\"${#authorization.expression('isAuthenticated()')}\"&gt;  \n                &lt;h1&gt;Who are you?&lt;\/h1&gt;  \n                &lt;a href=\"\/restricted\" class=\"btn btn-primary\"&gt;Restricted&lt;\/a&gt;  \n            &lt;\/div&gt;  \n        &lt;\/div&gt;  \n    &lt;\/div&gt;  \n&lt;\/div&gt;  \n&lt;\/body&gt;  \n&lt;\/html&gt;\n<\/pre>\n<p>The&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">thymeleaf-extras-springsecurity<\/code>&nbsp;plugin has some other nice features as well. If you want to dig a little deeper, check out&nbsp;<a href=\"https:\/\/github.com\/thymeleaf\/thymeleaf-extras-springsecurity\">the project repository on GitHub<\/a>.<\/p>\n<h2 class=\"wp-block-heading\">Secure Access By Group Membership<\/h2>\n<p>The next step in our tutorial is to add Group-based authentication using user groups that we\u2019ll create and define on Okta. A very common example of this is to have an \u201cadmin\u201d section of a website and a \u201cuser\u201d section of a website, along with perhaps a public home page open to everybody. In this example, \u201cadmin\u201d and \u201cuser\u201d would correspond to two different groups of which an authenticated user could be a member. What we want to do is be able to restrict access to URL endpoints based on user group membership, and to be able to assign users to these groups.<\/p>\n<p>A side note: groups vs roles. What\u2019s the difference?<\/p>\n<ul class=\"wp-block-list\">\n<li>A \u201cgroup\u201d is a collection of users, and permissions are assigned to the group. Generally speaking group membership is relatively static, at least throughout the duration of a session.<\/li>\n<li>A \u201crole\u201d is a set of permissions that a user can inherit when he\/she acts under that role. Roles are generally more dynamic in nature. Users can have many roles. Roles frequently are activated or deactivated depending on complex criteria and often may change throughout a user session.<\/li>\n<\/ul>\n<p>In practice, for simple authorization systems, they\u2019re pretty similar. The main difference is that groups classify based on individual identity, whereas roles classify based on permissible activities. You\u2019ll probably see apps and tutorials on the wild and woolly internet that ignore this difference, as it\u2019s functionally somewhat subtle. (But now you know. And you can get on the comment thread for the tutorial in question and write a comment correcting the author.)<\/p>\n<h2 class=\"wp-block-heading\">Configure Authorization Groups in Okta<\/h2>\n<p>Go to your&nbsp;<a href=\"https:\/\/developer.okta.com\/?utm_campaign=text_website_all_multiple_dev_ciam_webapp-spring-boot-security-15-min_null&amp;utm_source=jcg&amp;utm_medium=cpc\">developer.okta.com<\/a>&nbsp;dashboard. From the top menu, go to&nbsp;<strong>Users<\/strong>&nbsp;and click on&nbsp;<strong>Groups<\/strong>.<\/p>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter is-resized\"><img decoding=\"async\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/01\/6-1024x679.png\" alt=\"Web App\" class=\"wp-image-87548\" width=\"820\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/01\/6-1024x679.png 1024w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/01\/6-300x199.png 300w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/01\/6-768x509.png 768w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/01\/6.png 1075w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n<\/div>\n<p>Click on the&nbsp;<strong>Add Group<\/strong>&nbsp;button.<\/p>\n<p>Name the group \u201cAdmin\u201d and give it a description (I put \u201cAdministrators,\u201d doesn\u2019t matter what you put here really, just something descriptive).<\/p>\n<p>Click on the group Name to open the group and click on the&nbsp;<strong>Add Members<\/strong>&nbsp;button. Add your user to the Admin group.<\/p>\n<p>Next add a new user that\u2019s not an admin.<\/p>\n<ul class=\"wp-block-list\">\n<li>Go to&nbsp;<strong>Users<\/strong>&nbsp;from the top menu and click on&nbsp;<strong>People<\/strong>.<\/li>\n<li>Click&nbsp;<strong>Add Person<\/strong>.<\/li>\n<li>Fill out the popup form:\n<ul>\n<li>First name: Not<\/li>\n<li>Last name: Admin<\/li>\n<li>Username: notadmin@gmail.com<\/li>\n<li>No groups or secondary email<\/li>\n<li>Password: Set by admin<\/li>\n<li>Assign a password<\/li>\n<li>Uncheck \u201cUser must change password on first login\u201d<\/li>\n<li>Click&nbsp;<strong>Save<\/strong><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>The next thing you\u2019ll need to do is add a \u201cgroups\u201d claim to the default authorization server.<\/p>\n<ul class=\"wp-block-list\">\n<li>From the top menu, go to&nbsp;<strong>API<\/strong>&nbsp;and click on&nbsp;<strong>Authorization Servers<\/strong>\u201d<\/li>\n<li>Click on the&nbsp;<strong>default<\/strong>&nbsp;authorization server.<\/li>\n<li>Click on the&nbsp;<strong>Claims<\/strong>&nbsp;tab.<\/li>\n<li>Click the&nbsp;<strong>Add Claim<\/strong>&nbsp;button.<\/li>\n<li>Update the popup form to match the image below\n<ul>\n<li>Name: groups<\/li>\n<li>Token type: Access<\/li>\n<li>Value type: Groups<\/li>\n<li>Filter: Regex .*<\/li>\n<li>Don\u2019t disable<\/li>\n<li>Include in any scope<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img decoding=\"async\" width=\"811\" height=\"714\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/01\/7.png\" alt=\"Web App\" class=\"wp-image-87549\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/01\/7.png 811w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/01\/7-300x264.png 300w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/01\/7-768x676.png 768w\" sizes=\"(max-width: 811px) 100vw, 811px\" \/><\/figure>\n<\/div>\n<p>What you\u2019re doing here is telling Okta to include a \u201cgroups\u201d claim in the access token that is sent to your application. This is the OAuth method of Okta telling your application about the groups your authenticated user is a member of. Somewhat confusingly, these will be called \u201cauthorities\u201d on the Spring application side, which is an abstract term for groups\/roles\/privileges communicated by the OAuth server to the app.<\/p>\n<p>Now we have two users. Your primary user, which has been added to the Admin group, and a new user that is not in the admin group. We\u2019ve also configured Okta to add the groups claim to the access token. Now all we have to do is make a few changes to the app code!<\/p>\n<h2 class=\"wp-block-heading\">Update Your Spring Boot + Spring Security App to Use Group-based Authorization<\/h2>\n<p>This is where the Okta Spring Boot Starter really starts to shine. Normally if you wanted to map the security groups and groups claims that we are sending in the token to groups in the app, you\u2019d have to write an extractor class or two to handle the extraction, as well as perhaps a group class. The Okta Spring Boot Starter handles all of this for you!<\/p>\n<p>The first thing you\u2019re going to want to do is add the following annotation to your&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">SpringSecurityWebAppConfig<\/code>&nbsp;class.<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:java\">@EnableGlobalMethodSecurity(prePostEnabled = true)<\/pre>\n<p>Like so:<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:java; wrap-lines:false\">import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;\n\n@EnableOAuth2Sso  \n@Configuration  \n@EnableGlobalMethodSecurity(prePostEnabled = true)  \npublic class SpringSecurityWebAppConfig extends WebSecurityConfigurerAdapter {  \n    \/* class contents omitted for brevity *\/\n}\n<\/pre>\n<p>This annotation enables the next annotation that we\u2019re going to use, the&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">@PreAuthorize<\/code>&nbsp;annotation. This annotation allows us to use a Spring Expression Language (SpEL) predicate to determine if the controller method is authorized. The predicate expression is executed before the app even enters the controller method (hence the \u201cpre\u201d-authorize).<\/p>\n<p>In the&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">SimpleAppController<\/code>&nbsp;class, add a new method called&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">admin<\/code>&nbsp;like so:<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:java\">import org.springframework.security.access.prepost.PreAuthorize;\n\n@Controller  \nclass SimpleAppController {  \n      \n    \/* other controllers omitted for clarity *\/ \n  \n    @RequestMapping(\"\/admin\")  \n    @PreAuthorize(\"hasAuthority('Admin')\")  \n    String admin() {  \n        return \"admin\";  \n    }  \n  \n}\n<\/pre>\n<p>Just to recap a little, this method does the following:<\/p>\n<ul class=\"wp-block-list\">\n<li>create a mapping for the&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">\/admin<\/code>&nbsp;url endpoint;<\/li>\n<li>assign the&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">\/admin<\/code>&nbsp;endpoint an authorization scheme based on SpEL;<\/li>\n<li>and simply return the name of a Thymeleaf template, assumed to be in the&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">\/templates<\/code>&nbsp;directory (which we\u2019ll create next).<\/li>\n<\/ul>\n<p>Create the new admin template page. In the&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">src\/main\/resources\/templates<\/code>&nbsp;directory, create a new file called&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">admin.html<\/code>&nbsp;with the following contents:<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:xml; wrap-lines:false\">&lt;html xmlns:th=\"http:\/\/www.thymeleaf.org\" xmlns:sec=\"http:\/\/www.thymeleaf.org\/thymeleaf-extras-springsecurity4\"&gt;  \n&lt;head&gt;  \n    &lt;!--\/*\/ &lt;th:block th:include=\"fragments\/head :: head\"\/&gt; \/*\/--&gt;  \n&lt;\/head&gt;  \n&lt;body&gt;  \n&lt;div class=\"container-fluid\"&gt;  \n    &lt;div class=\"row\"&gt;  \n        &lt;div class=\"box col-md-6 col-md-offset-3\"&gt;  \n            &lt;div class=\"okta-header\"&gt;  \n                &lt;img src=\"img\/logo.png\"\/&gt;  \n            &lt;\/div&gt;  \n              \n            &lt;h1&gt;Welcome to the admin page!&lt;\/h1&gt;  \n  \n            &lt;a href=\"\/\" class=\"btn btn-primary\"&gt;Go Home&lt;\/a&gt;  \n  \n        &lt;\/div&gt;  \n    &lt;\/div&gt;  \n&lt;\/div&gt;  \n&lt;\/body&gt;  \n&lt;\/html&gt;\n<\/pre>\n<p>You may be asking yourself what the SpEL expression used in the&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">@PreAuthorize<\/code>&nbsp;annotation means. Why is the SpEL expression&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">hasAuthority<\/code>&nbsp;and not&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">hasGroup<\/code>? A correct answer is somewhat complicated, having to do with the fact that Spring calls permissions privileges and authorities in different contexts, which can be mapped to groups and roles in the app. When using Spring Boot and OAuth, an \u2018authority\u2019 is often equated with a \u2018role\u2019, which is fine. But you said we\u2019re using groups, not roles? Right. Practically speaking, in this instance, it doesn\u2019t matter because Okta knows we\u2019re talking about groups and the app knows we\u2019re talking about groups, and in the middle we just use the groups claim and the authorities fields to communicate the text strings that represent the groups the user is a member of.<\/p>\n<p><strong>A helpful hint:<\/strong><\/p>\n<p>If you want to inspect the authentication information that the Spring Boot App is receiving, you can add the following line in one of the controller methods before the return statement.<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:bash\">Authentication authentication = SecurityContextHolder.getContext().getAuthentication();<\/pre>\n<p>Set a breakpoint on this line, or right after it, really, and run the app with a debugger that allows you to inspect the authentication object. It\u2019s a great way to learn and debug problems.<\/p>\n<h2 class=\"wp-block-heading\">Try Out Your New Spring Boot + Spring Security Web App!<\/h2>\n<p>That\u2019s pretty much it. You should be able to restart the app and log in with two different users. Only the user that was added to the Admin group should be able to access the admin page. You\u2019ll have to directly navigate to http:\/\/localhost:8080\/admin (as we didn\u2019t add a link or a button). If you try to navigate to the admin page with the other user, you\u2019ll see the beautiful whitelabel error page showing a 403 \/ Unauthorized error.<\/p>\n<p>Keep in mind that when switching between users you\u2019ll have to stop the app, log out of your developer.okta.com account, and restart the app. You can also use an incognito window in your browser.<\/p>\n<p>This part of the tutorial corresponds to the&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">GroupsAuth<\/code>&nbsp;tag, which you can checkout using the following command&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">git checkout tags\/GroupsAuth<\/code>.<\/p>\n<h2 class=\"wp-block-heading\">Learn More About Spring Boot, Spring Security, and Secure User Management<\/h2>\n<p>You made some real progress here. You saw how to create a simple Spring Boot app and how to use Thymeleaf templates. You\u2019ve seen how easy Okta makes it to integrate OAuth 2.0 Single Sign-On into your app. You\u2019ve seen how to restrict access to controller endpoints using a&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">WebSecurityConfigurerAdapter<\/code>&nbsp;subclass and the&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">http.authorizeRequests()<\/code>&nbsp;fluent API.<\/p>\n<p>And finally, you\u2019ve seen how to create groups and users on Okta, how to tie those into your Spring Boot app, and how to use the&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">@PreAuthorize<\/code>&nbsp;annotation to configure authorization based on group membership.<\/p>\n<p>If you\u2019d like to check out this complete project, you can find the repo on Github at:&nbsp;<a href=\"https:\/\/github.com\/moksamedia\/okta-spring-simple-app\">https:\/\/github.com\/moksamedia\/okta-spring-simple-app<\/a>.<\/p>\n<p>If you\u2019d like to learn more about Spring Boot, Spring Security, or Okta, check out any of these great tutorials:<\/p>\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/developer.okta.com\/blog\/2017\/03\/21\/spring-boot-oauth?utm_campaign=text_website_all_multiple_dev_ciam_webapp-spring-boot-security-15-min_null&amp;utm_source=jcg&amp;utm_medium=cpc\">Get Started with Spring Boot, OAuth 2.0, and Okta<\/a><\/li>\n<li><a href=\"https:\/\/developer.okta.com\/blog\/2017\/11\/20\/add-sso-spring-boot-15-min?utm_campaign=text_website_all_multiple_dev_ciam_webapp-spring-boot-security-15-min_null&amp;utm_source=jcg&amp;utm_medium=cpc\">Add Single Sign-On to Your Spring Boot Web App in 15 Minutes<\/a><\/li>\n<li><a href=\"https:\/\/developer.okta.com\/blog\/2018\/06\/12\/mfa-in-spring-boot?utm_campaign=text_website_all_multiple_dev_ciam_webapp-spring-boot-security-15-min_null&amp;utm_source=jcg&amp;utm_medium=cpc\">Secure Your Spring Boot Application with Multi-Factor Authentication<\/a><\/li>\n<li><a href=\"https:\/\/developer.okta.com\/blog\/2018\/08\/16\/secure-api-spring-boot-graphql?utm_campaign=text_website_all_multiple_dev_ciam_webapp-spring-boot-security-15-min_null&amp;utm_source=jcg&amp;utm_medium=cpc\">Build a Secure API with Spring Boot and GraphQL<\/a><\/li>\n<\/ul>\n<p>If you want to dive deeper, take a look at the&nbsp;<a href=\"https:\/\/github.com\/okta\/okta-spring-boot\">Okta Spring Boot Starter GitHub page<\/a>.<\/p>\n<p>If you have any questions about this post, please add a comment below. For more awesome content, follow&nbsp;<a href=\"https:\/\/twitter.com\/oktadev\">@oktadev<\/a>&nbsp;on Twitter, like us&nbsp;<a href=\"https:\/\/www.facebook.com\/oktadevelopers\/\">on Facebook<\/a>, or subscribe to&nbsp;<a href=\"https:\/\/www.youtube.com\/channel\/UC5AMiWqFVFxF1q9Ya1FuZ_Q\">our YouTube channel<\/a>.<\/p>\n<p><span style=\"font-size: 20px;\"><b>\u201cI love writing authentication and authorization code.\u201d ~ No Java Developer Ever.<\/b> Tired of building the same login screens over and over? <a href=\"https:\/\/developer.okta.com\/signup?utm_campaign=text_website_all_multiple_dev_ciam_webapp-spring-boot-security-15-min_null&amp;utm_source=jcg&amp;utm_medium=cpc\">Try the Okta API for hosted authentication, authorization, and multi-factor auth.<\/a><\/span><\/p>\n<p><a href=\"https:\/\/developer.okta.com\/blog\/2018\/09\/26\/build-a-spring-boot-webapp?utm_campaign=text_website_all_multiple_dev_ciam_webapp-spring-boot-security-15-min_null&amp;utm_source=jcg&amp;utm_medium=cpc\" target=\"_blank\" rel=\"noopener\" data-saferedirecturl=\"https:\/\/www.google.com\/url?q=https:\/\/developer.okta.com\/blog\/2018\/09\/26\/build-a-spring-boot-webapp&amp;source=gmail&amp;ust=1548920141106000&amp;usg=AFQjCNFRLUDqF4cHoH6GLtyNknoSHFYLOA\">&#8220;Build a Web App with Spring Boot and Spring Security in 15 Minutes&#8221;<\/a>&nbsp;was originally published on the Okta developer blog on September 26, 2018.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u201cI love writing authentication and authorization code.\u201d ~ No Java Developer Ever. Tired of building the same login screens over and over? Try the Okta API for hosted authentication, authorization, and multi-factor auth. Developers know that securing web apps can be a pain. Doing it right is tough. The worst part is that \u201cright\u201d is &hellip;<\/p>\n","protected":false},"author":49514,"featured_media":240,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[30,854,125],"class_list":["post-87537","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-enterprise-java","tag-spring","tag-spring-boot","tag-spring-security"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Build a Web App with Spring Boot and Spring Security in 15 Minutes - Java Code Geeks<\/title>\n<meta name=\"description\" content=\"Interested to learn about Web App? Check our article explaining how to Build a Web App with Spring Boot and Spring Security in just a few minutes.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/developer.okta.com\/blog\/2018\/09\/26\/build-a-spring-boot-webapp\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Build a Web App with Spring Boot and Spring Security in 15 Minutes - Java Code Geeks\" \/>\n<meta property=\"og:description\" content=\"Interested to learn about Web App? Check our article explaining how to Build a Web App with Spring Boot and Spring Security in just a few minutes.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/developer.okta.com\/blog\/2018\/09\/26\/build-a-spring-boot-webapp\" \/>\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=\"2019-02-04T07:29:50+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2019-02-11T08:08:03+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=\"Andrew Hughes\" \/>\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=\"Andrew Hughes\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"21 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/developer.okta.com\\\/blog\\\/2018\\\/09\\\/26\\\/build-a-spring-boot-webapp#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2019\\\/02\\\/build-web-app-spring-boot-spring-security.html\"},\"author\":{\"name\":\"Andrew Hughes\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/0ded99ab51010abb68790f6189ce99d3\"},\"headline\":\"Build a Web App with Spring Boot and Spring Security in 15 Minutes\",\"datePublished\":\"2019-02-04T07:29:50+00:00\",\"dateModified\":\"2019-02-11T08:08:03+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2019\\\/02\\\/build-web-app-spring-boot-spring-security.html\"},\"wordCount\":3431,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/developer.okta.com\\\/blog\\\/2018\\\/09\\\/26\\\/build-a-spring-boot-webapp#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/spring-logo.jpg\",\"keywords\":[\"Spring\",\"Spring Boot\",\"Spring Security\"],\"articleSection\":[\"Enterprise Java\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/developer.okta.com\\\/blog\\\/2018\\\/09\\\/26\\\/build-a-spring-boot-webapp#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2019\\\/02\\\/build-web-app-spring-boot-spring-security.html\",\"url\":\"https:\\\/\\\/developer.okta.com\\\/blog\\\/2018\\\/09\\\/26\\\/build-a-spring-boot-webapp\",\"name\":\"Build a Web App with Spring Boot and Spring Security in 15 Minutes - Java Code Geeks\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/developer.okta.com\\\/blog\\\/2018\\\/09\\\/26\\\/build-a-spring-boot-webapp#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/developer.okta.com\\\/blog\\\/2018\\\/09\\\/26\\\/build-a-spring-boot-webapp#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/spring-logo.jpg\",\"datePublished\":\"2019-02-04T07:29:50+00:00\",\"dateModified\":\"2019-02-11T08:08:03+00:00\",\"description\":\"Interested to learn about Web App? Check our article explaining how to Build a Web App with Spring Boot and Spring Security in just a few minutes.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/developer.okta.com\\\/blog\\\/2018\\\/09\\\/26\\\/build-a-spring-boot-webapp#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/developer.okta.com\\\/blog\\\/2018\\\/09\\\/26\\\/build-a-spring-boot-webapp\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/developer.okta.com\\\/blog\\\/2018\\\/09\\\/26\\\/build-a-spring-boot-webapp#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:\\\/\\\/developer.okta.com\\\/blog\\\/2018\\\/09\\\/26\\\/build-a-spring-boot-webapp#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\":\"Build a Web App with Spring Boot and Spring Security in 15 Minutes\"}]},{\"@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\\\/0ded99ab51010abb68790f6189ce99d3\",\"name\":\"Andrew Hughes\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/703689ecb161268c8a6ca8ad4057b8342d22972ec435111a055712b399716dbd?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/703689ecb161268c8a6ca8ad4057b8342d22972ec435111a055712b399716dbd?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/703689ecb161268c8a6ca8ad4057b8342d22972ec435111a055712b399716dbd?s=96&d=mm&r=g\",\"caption\":\"Andrew Hughes\"},\"sameAs\":[\"https:\\\/\\\/developer.okta.com\\\/blog\"],\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/author\\\/andrew-hughes\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Build a Web App with Spring Boot and Spring Security in 15 Minutes - Java Code Geeks","description":"Interested to learn about Web App? Check our article explaining how to Build a Web App with Spring Boot and Spring Security in just a few minutes.","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:\/\/developer.okta.com\/blog\/2018\/09\/26\/build-a-spring-boot-webapp","og_locale":"en_US","og_type":"article","og_title":"Build a Web App with Spring Boot and Spring Security in 15 Minutes - Java Code Geeks","og_description":"Interested to learn about Web App? Check our article explaining how to Build a Web App with Spring Boot and Spring Security in just a few minutes.","og_url":"https:\/\/developer.okta.com\/blog\/2018\/09\/26\/build-a-spring-boot-webapp","og_site_name":"Java Code Geeks","article_publisher":"https:\/\/www.facebook.com\/javacodegeeks","article_published_time":"2019-02-04T07:29:50+00:00","article_modified_time":"2019-02-11T08:08:03+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":"Andrew Hughes","twitter_card":"summary_large_image","twitter_creator":"@javacodegeeks","twitter_site":"@javacodegeeks","twitter_misc":{"Written by":"Andrew Hughes","Est. reading time":"21 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/developer.okta.com\/blog\/2018\/09\/26\/build-a-spring-boot-webapp#article","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/2019\/02\/build-web-app-spring-boot-spring-security.html"},"author":{"name":"Andrew Hughes","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/0ded99ab51010abb68790f6189ce99d3"},"headline":"Build a Web App with Spring Boot and Spring Security in 15 Minutes","datePublished":"2019-02-04T07:29:50+00:00","dateModified":"2019-02-11T08:08:03+00:00","mainEntityOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2019\/02\/build-web-app-spring-boot-spring-security.html"},"wordCount":3431,"commentCount":0,"publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"image":{"@id":"https:\/\/developer.okta.com\/blog\/2018\/09\/26\/build-a-spring-boot-webapp#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","keywords":["Spring","Spring Boot","Spring Security"],"articleSection":["Enterprise Java"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/developer.okta.com\/blog\/2018\/09\/26\/build-a-spring-boot-webapp#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.javacodegeeks.com\/2019\/02\/build-web-app-spring-boot-spring-security.html","url":"https:\/\/developer.okta.com\/blog\/2018\/09\/26\/build-a-spring-boot-webapp","name":"Build a Web App with Spring Boot and Spring Security in 15 Minutes - Java Code Geeks","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/developer.okta.com\/blog\/2018\/09\/26\/build-a-spring-boot-webapp#primaryimage"},"image":{"@id":"https:\/\/developer.okta.com\/blog\/2018\/09\/26\/build-a-spring-boot-webapp#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","datePublished":"2019-02-04T07:29:50+00:00","dateModified":"2019-02-11T08:08:03+00:00","description":"Interested to learn about Web App? Check our article explaining how to Build a Web App with Spring Boot and Spring Security in just a few minutes.","breadcrumb":{"@id":"https:\/\/developer.okta.com\/blog\/2018\/09\/26\/build-a-spring-boot-webapp#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/developer.okta.com\/blog\/2018\/09\/26\/build-a-spring-boot-webapp"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/developer.okta.com\/blog\/2018\/09\/26\/build-a-spring-boot-webapp#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:\/\/developer.okta.com\/blog\/2018\/09\/26\/build-a-spring-boot-webapp#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":"Build a Web App with Spring Boot and Spring Security in 15 Minutes"}]},{"@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\/0ded99ab51010abb68790f6189ce99d3","name":"Andrew Hughes","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/703689ecb161268c8a6ca8ad4057b8342d22972ec435111a055712b399716dbd?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/703689ecb161268c8a6ca8ad4057b8342d22972ec435111a055712b399716dbd?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/703689ecb161268c8a6ca8ad4057b8342d22972ec435111a055712b399716dbd?s=96&d=mm&r=g","caption":"Andrew Hughes"},"sameAs":["https:\/\/developer.okta.com\/blog"],"url":"https:\/\/www.javacodegeeks.com\/author\/andrew-hughes"}]}},"_links":{"self":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/87537","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\/49514"}],"replies":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/comments?post=87537"}],"version-history":[{"count":0,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/87537\/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=87537"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/categories?post=87537"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/tags?post=87537"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}