diff --git a/articles/microsites/call-api/call-api-m2m-app.md b/articles/microsites/call-api/call-api-m2m-app.md index 51dcd34287..5f8d1154f5 100644 --- a/articles/microsites/call-api/call-api-m2m-app.md +++ b/articles/microsites/call-api/call-api-m2m-app.md @@ -3,6 +3,7 @@ title: Call Your API from a Machine-to-Machine App description: Everything you need to know to call your API from your machine-to-machine (M2M) app ctaText: Go to Quickstart ctaLink: /docs/quickstart/backend +public: false template: microsite topics: - authentication diff --git a/articles/quickstart/backend/java-spring-security5/01-authorization.md b/articles/quickstart/backend/java-spring-security5/01-authorization.md index 2b6fb145ea..fa3cf07bb4 100644 --- a/articles/quickstart/backend/java-spring-security5/01-authorization.md +++ b/articles/quickstart/backend/java-spring-security5/01-authorization.md @@ -1,7 +1,7 @@ --- title: Authorization -name: How to secure your API using Spring Security 5 and Auth0 -description: This tutorial demonstrates how to add authorization to an API using Spring Security 5. +name: How to secure your API with Spring Boot +description: This tutorial demonstrates how to add authorization to an API using the Okta Spring Boot Starter. budicon: 500 topics: - quickstart @@ -30,24 +30,20 @@ This Quickstart uses Spring MVC. If you are using Spring WebFlux, the steps to s The sample project uses a `/src/main/resources/application.yml` file, which configures it to use the correct Auth0 **Domain** and **API Identifier** for your API. If you download the code from this page it will be automatically configured. If you clone the example from GitHub, you will need to fill it in yourself. ```yaml -auth0: - audience: ${apiIdentifier} -spring: - security: - oauth2: - resourceserver: - jwt: - issuer-uri: https://${account.namespace}/ +okta: + oauth2: + # Replace with the domain of your Auth0 tenant. + issuer: https://${account.namespace}/ + # Replace with the API Identifier for your Auth0 API. + audience: ${apiIdentifier} ``` | Attribute | Description| | --- | --- | -| `auth0.audience` | The unique identifier for your API. If you are following the steps in this tutorial it would be `https://quickstarts/api`. | -| `spring.security.oauth2.resourceserver.jwt.issuer-uri` | The issuer URI of the resource server, which will be the value of the `iss` claim in the JWT issued by Auth0. Spring Security will use this property to discover the authorization server's public keys and validate the JWT signature. The value will be your Auth0 domain with an `https://` prefix and a `/` suffix (the trailing slash is important). | +| `okta.oauth2.audience` | The unique identifier for your API. If you are following the steps in this tutorial it would be `https://quickstarts/api`. | +| `okta.oauth2.issuer` | The issuer URI of the resource server, which will be the value of the `iss` claim in the JWT issued by Auth0. Spring Security will use this property to discover the authorization server's public keys and validate the JWT signature. The value will be your Auth0 domain with an `https://` prefix and a `/` suffix (the trailing slash is important). | -## Validate Access Tokens - -### Install dependencies +## Install dependencies If you are using Gradle, you can add the required dependencies using the [Spring Boot Gradle Plugin](https://docs.spring.io/spring-boot/docs/current/gradle-plugin/reference/html/) and the [Dependency Management Plugin](https://docs.spring.io/dependency-management-plugin/docs/current/reference/html/) to resolve dependency versions: @@ -55,13 +51,14 @@ If you are using Gradle, you can add the required dependencies using the [Spring // build.gradle plugins { - id 'org.springframework.boot' version '2.5.12' - id 'io.spring.dependency-management' version '1.0.9.RELEASE' + id 'java' + id 'org.springframework.boot' version '3.1.5' + id 'io.spring.dependency-management' version '1.1.3' } dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' - implementation 'org.springframework.boot:spring-boot-starter-oauth2-resource-server' + implementation 'com.okta.spring:okta-spring-boot-starter:3.0.5' } ``` @@ -73,7 +70,7 @@ If you are using Maven, add the Spring dependencies to your `pom.xml` file: org.springframework.boot spring-boot-starter-parent - 2.5.12 + 3.1.5 @@ -83,113 +80,19 @@ If you are using Maven, add the Spring dependencies to your `pom.xml` file: spring-boot-starter-web - org.springframework.boot - spring-boot-starter-oauth2-resource-server + com.okta + okta-spring-boot-starter + 3.0.5 ``` -### Configure the resource server - -To configure the application as a Resource Server and validate the JWTs, create a class that will provide an instance of `SecurityFilterChain`, and add the `@EnableWebSecurity` annotation: - -```java -// src/main/java/com/auth0/example/security/SecurityConfig.java - -import org.springframework.context.annotation.Bean; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.web.SecurityFilterChain; - -@EnableWebSecurity -public class SecurityConfig { - - @Bean - public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { - http.oauth2Login(); - return http.build(); - } -} -``` - -### Validate the audience - -> Note: If you are using Spring Boot version 2.7 or higher, audience validation is supported out of the box by Spring Security. Instead of customizing beans as indicated below, you should just include the Auth0 API identifier as a value in the `spring.security.oauth2.resourceserver.jwt.audiences` array. -> Example: `spring.security.oauth2.resourceserver.jwt.audiences=http://api-identifier` - -In addition to validating the JWT, you also need to validate that the JWT is intended for your API by checking the `aud` claim of the JWT. Create a new class named `AudienceValidator` that implements the `OAuth2TokenValidator` interface: - -```java -// src/main/java/com/auth0/example/security/AudienceValidator.java - -import org.springframework.security.oauth2.core.OAuth2Error; -import org.springframework.security.oauth2.core.OAuth2TokenValidator; -import org.springframework.security.oauth2.core.OAuth2TokenValidatorResult; -import org.springframework.security.oauth2.jwt.Jwt; - -class AudienceValidator implements OAuth2TokenValidator { - private final String audience; - - AudienceValidator(String audience) { - this.audience = audience; - } - - public OAuth2TokenValidatorResult validate(Jwt jwt) { - OAuth2Error error = new OAuth2Error("invalid_token", "The required audience is missing", null); - - if (jwt.getAudience().contains(audience)) { - return OAuth2TokenValidatorResult.success(); - } - return OAuth2TokenValidatorResult.failure(error); - } -} -``` - -Update the `SecurityConfig` class to configure a `JwtDecoder` bean that uses the `AudienceValidator`: - -```java -// src/main/java/com/auth0/example/security/SecurityConfig.java - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Bean; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.oauth2.core.DelegatingOAuth2TokenValidator; -import org.springframework.security.oauth2.core.OAuth2TokenValidator; -import org.springframework.security.oauth2.jwt.Jwt; -import org.springframework.security.oauth2.jwt.JwtDecoder; -import org.springframework.security.oauth2.jwt.JwtDecoders; -import org.springframework.security.oauth2.jwt.JwtValidators; -import org.springframework.security.oauth2.jwt.NimbusJwtDecoder; - -@EnableWebSecurity -public class SecurityConfig { - - @Value("<%= "${auth0.audience}" %>") - private String audience; - - @Value("<%= "${spring.security.oauth2.resourceserver.jwt.issuer-uri}" %>") - private String issuer; - - @Bean - JwtDecoder jwtDecoder() { - NimbusJwtDecoder jwtDecoder = (NimbusJwtDecoder) - JwtDecoders.fromOidcIssuerLocation(issuer); - - OAuth2TokenValidator audienceValidator = new AudienceValidator(audience); - OAuth2TokenValidator withIssuer = JwtValidators.createDefaultWithIssuer(issuer); - OAuth2TokenValidator withAudience = new DelegatingOAuth2TokenValidator<>(withIssuer, audienceValidator); - - jwtDecoder.setJwtValidator(withAudience); - - return jwtDecoder; - } -} -``` - -## Protect API Endpoints +## Protect API endpoints <%= include('../_includes/_api_endpoints') %> +To configure the application as a Resource Server and validate the JWTs, create a class that will register a [SecurityFilterChain](https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/web/SecurityFilterChain.html), an instance of `SecurityFilterChain`, and add the `@Configuration` annotation. + The example below shows how to secure API methods using the `HttpSecurity` object provided in the `filterChain()` method of the `SecurityConfig` class. Route matchers are used to restrict access based on the level of authorization required: ```java @@ -218,28 +121,16 @@ public class SecurityConfig { ::: note By default, Spring Security will create a `GrantedAuthority` for each scope in the `scope` claim of the JWT. This is what enables using the `hasAuthority("SCOPE_read:messages")` method to restrict access to a valid JWT that contains the `read:messages` scope. - -If your use case requires different claims to make authorization decisions, see the [Spring Security Reference Documentation](https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#oauth2resourceserver-authorization-extraction) to learn how to customize the extracted authorities. ::: ### Create the API controller -Create a new class named `Message`, which is the domain object the API will return: +Create a new record named `Message`, which will be the domain object the API will return: ```java // src/main/java/com/auth0/example/model/Message.java -public class Message { - private final String message; - - public Message(String message) { - this.message = message; - } - - public String getMessage() { - return this.message; - } -} +public record Message(String message) {} ``` Create a new class named `APIController` to handle requests to the endpoints: @@ -254,6 +145,10 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +/** + * Handles requests to "/api" endpoints. + * @see com.auth0.example.security.SecurityConfig to see how these endpoints are protected. + */ @RestController @RequestMapping(path = "api", produces = MediaType.APPLICATION_JSON_VALUE) // For simplicity of this sample, allow all origins. Real applications should configure CORS for their use case. diff --git a/articles/quickstart/backend/java-spring-security5/files/application.md b/articles/quickstart/backend/java-spring-security5/files/application.md index 8b101d0381..f12a521ce0 100644 --- a/articles/quickstart/backend/java-spring-security5/files/application.md +++ b/articles/quickstart/backend/java-spring-security5/files/application.md @@ -3,12 +3,10 @@ name: application.yml language: yaml --- ```yaml -auth0: - audience: ${apiIdentifier} -spring: - security: - oauth2: - resourceserver: - jwt: - issuer-uri: https://${account.namespace}/ +okta: + oauth2: + # Replace with the domain of your Auth0 tenant. + issuer: https://${account.namespace}/ + # Replace with the API Identifier for your Auth0 API. + audience: ${apiIdentifier} ``` \ No newline at end of file diff --git a/articles/quickstart/backend/java-spring-security5/files/audience-validator.md b/articles/quickstart/backend/java-spring-security5/files/audience-validator.md deleted file mode 100644 index 4dee42194d..0000000000 --- a/articles/quickstart/backend/java-spring-security5/files/audience-validator.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -name: AudienceValidator.java -language: java ---- -```java -import org.springframework.security.oauth2.core.OAuth2Error; -import org.springframework.security.oauth2.core.OAuth2TokenValidator; -import org.springframework.security.oauth2.core.OAuth2TokenValidatorResult; -import org.springframework.security.oauth2.jwt.Jwt; - -class AudienceValidator implements OAuth2TokenValidator { - private final String audience; - - AudienceValidator(String audience) { - this.audience = audience; - } - - public OAuth2TokenValidatorResult validate(Jwt jwt) { - OAuth2Error error = new OAuth2Error("invalid_token", "The required audience is missing", null); - - if (jwt.getAudience().contains(audience)) { - return OAuth2TokenValidatorResult.success(); - } - return OAuth2TokenValidatorResult.failure(error); - } -} -``` \ No newline at end of file diff --git a/articles/quickstart/backend/java-spring-security5/files/message.md b/articles/quickstart/backend/java-spring-security5/files/message.md index 2b5a51290a..99f4056914 100644 --- a/articles/quickstart/backend/java-spring-security5/files/message.md +++ b/articles/quickstart/backend/java-spring-security5/files/message.md @@ -3,15 +3,9 @@ name: Message.java language: java --- ```java -public class Message { - private final String message; +/** + * Simple domain object for our API to return a message. + */ +public record Message(String message) {} - public Message(String message) { - this.message = message; - } - - public String getMessage() { - return this.message; - } -} ``` \ No newline at end of file diff --git a/articles/quickstart/backend/java-spring-security5/files/security-config.md b/articles/quickstart/backend/java-spring-security5/files/security-config.md index fe9d549af1..257bdbaa32 100644 --- a/articles/quickstart/backend/java-spring-security5/files/security-config.md +++ b/articles/quickstart/backend/java-spring-security5/files/security-config.md @@ -3,59 +3,40 @@ name: SecurityConfig.java language: java --- ```java -import org.springframework.beans.factory.annotation.Value; +package com.auth0.example.security; + + import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.oauth2.core.DelegatingOAuth2TokenValidator; -import org.springframework.security.oauth2.core.OAuth2TokenValidator; -import org.springframework.security.oauth2.jwt.*; import org.springframework.security.web.SecurityFilterChain; +import static org.springframework.security.config.Customizer.withDefaults; + /** * Configures our application with Spring Security to restrict access to our API endpoints. */ -@EnableWebSecurity +@Configuration public class SecurityConfig { - @Value("<%= "${auth0.audience}" %>") - private String audience; - - @Value("<%= "${spring.security.oauth2.resourceserver.jwt.issuer-uri}" %>") - private String issuer; - @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { /* This is where we configure the security required for our endpoints and setup our app to serve as an OAuth2 Resource Server, using JWT validation. */ - http.authorizeRequests() - .mvcMatchers("/api/public").permitAll() - .mvcMatchers("/api/private").authenticated() - .mvcMatchers("/api/private-scoped").hasAuthority("SCOPE_read:messages") - .and().cors() - .and().oauth2ResourceServer().jwt(); - return http.build(); - } - - @Bean - JwtDecoder jwtDecoder() { - /* - By default, Spring Security does not validate the "aud" claim of the token, to ensure that this token is - indeed intended for our app. Adding our own validator is easy to do: - */ - - NimbusJwtDecoder jwtDecoder = (NimbusJwtDecoder) - JwtDecoders.fromOidcIssuerLocation(issuer); - - OAuth2TokenValidator audienceValidator = new AudienceValidator(audience); - OAuth2TokenValidator withIssuer = JwtValidators.createDefaultWithIssuer(issuer); - OAuth2TokenValidator withAudience = new DelegatingOAuth2TokenValidator<>(withIssuer, audienceValidator); - - jwtDecoder.setJwtValidator(withAudience); - - return jwtDecoder; + return http + .authorizeHttpRequests((authorize) -> authorize + .requestMatchers("/api/public").permitAll() + .requestMatchers("/api/private").authenticated() + .requestMatchers("/api/private-scoped").hasAuthority("SCOPE_read:messages") + ) + .cors(withDefaults()) + .oauth2ResourceServer(oauth2 -> oauth2 + .jwt(withDefaults()) + ) + .build(); } } + ``` \ No newline at end of file diff --git a/articles/quickstart/backend/java-spring-security5/index.yml b/articles/quickstart/backend/java-spring-security5/index.yml index 1cac540d5e..9baab5db4c 100644 --- a/articles/quickstart/backend/java-spring-security5/index.yml +++ b/articles/quickstart/backend/java-spring-security5/index.yml @@ -8,8 +8,8 @@ author: email: jim.anderson@auth0.com community: false sdk: - name: auth0-spring-security-api - url: https://github.com/auth0/auth0-spring-security-api + name: Okta Spring Boot Starter + url: https://github.com/okta/okta-spring-boot/ logo: spring alias: - spring security @@ -34,7 +34,7 @@ github: org: auth0-samples repo: auth0-spring-security5-api-sample requirements: - - Java 8 or above + - Java 17 next_steps: - path: 01-authorization list: diff --git a/articles/quickstart/backend/java-spring-security5/interactive.md b/articles/quickstart/backend/java-spring-security5/interactive.md index 4d09273327..bae669d759 100644 --- a/articles/quickstart/backend/java-spring-security5/interactive.md +++ b/articles/quickstart/backend/java-spring-security5/interactive.md @@ -11,7 +11,6 @@ topics: - spring files: - files/application - - files/audience-validator - files/security-config - files/message - files/api-controller @@ -40,8 +39,8 @@ The sample project uses a `/src/main/resources/application.yml` file, which conf | Attribute | Description| | --- | --- | -| `auth0.audience` | The unique identifier for your API. If you are following the steps in this tutorial it would be `https://quickstarts/api`. | -| `spring.security.oauth2.resourceserver.jwt.issuer-uri` | The value of the `iss` claim and the issuer URI of the resource server in the JWT issued by Auth0. Spring Security uses this property to discover the authorization server's public keys and validate the JWT signature. The value is Auth0 domain with an `https://` prefix and a `/` suffix (the trailing slash is important). | +| `okta.oauth2.audience` | The unique identifier for your API. If you are following the steps in this tutorial it would be `https://quickstarts/api`. | +| `okta.oauth2.issuer` | The issuer URI of the resource server, which will be the value of the `iss` claim in the JWT issued by Auth0. Spring Security will use this property to discover the authorization server's public keys and validate the JWT signature. The value will be your Auth0 domain with an `https://` prefix and a `/` suffix (the trailing slash is important). ## Install dependencies {{{ data-action=code data-code="application.yml#1:8" }}} @@ -51,13 +50,14 @@ If you are using Gradle, you can add the required dependencies using the [Spring // build.gradle plugins { - id 'org.springframework.boot' version '2.5.12' - id 'io.spring.dependency-management' version '1.0.9.RELEASE' + id 'java' + id 'org.springframework.boot' version '3.1.5' + id 'io.spring.dependency-management' version '1.1.3' } dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' - implementation 'org.springframework.boot:spring-boot-starter-oauth2-resource-server' + implementation 'com.okta.spring:okta-spring-boot-starter:3.0.5' } ``` @@ -69,7 +69,7 @@ If you are using Maven, add the Spring dependencies to your `pom.xml` file: org.springframework.boot spring-boot-starter-parent - 2.5.12 + 3.1.5 @@ -79,39 +79,31 @@ If you are using Maven, add the Spring dependencies to your `pom.xml` file: spring-boot-starter-web - org.springframework.boot - spring-boot-starter-oauth2-resource-server + com.okta + okta-spring-boot-starter + 3.0.5 ``` -## Validate the audience {{{ data-action=code data-code="AudienceValidator.java#13:20" }}} - -To validate the JWT, you also need to validate that the JWT is intended for your API by checking the `aud` claim of the JWT. Create a new class named `AudienceValidator` that implements the `OAuth2TokenValidator` interface and override the `validate` method to verify whether the required `audience` is present. ## Configure the resource server {{{ data-action=code data-code="SecurityConfig.java" }}} -To configure the application as a Resource Server and validate the JWTs, create a class that will provide an instance of `SecurityFilterChain`, and add the `@EnableWebSecurity` annotation: +To configure the application as a Resource Server and validate the JWTs, create a class that will provide an instance of `SecurityFilterChain`, and add the `@Configuration` annotation. ### Protect API endpoints <%= include('../_includes/_api_endpoints') %> -The example below shows how to secure API methods using the `HttpSecurity` object provided in the `filterChain()` method of the `SecurityConfig` class. Route matchers restrict access based on the level of authorization required: +The example below shows how to secure API methods using the `HttpSecurity` object provided in the `filterChain()` method of the `SecurityConfig` class. Route matchers restrict access based on the level of authorization required. ::: note By default, Spring Security creates a `GrantedAuthority` for each scope in the `scope` claim of the JWT. This scope enables using the `hasAuthority("SCOPE_read:messages")` method to restrict access to a valid JWT that contains the `read:messages` scope. - -If your use case requires different claims to make authorization decisions, see the [Spring Security Reference Documentation](https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#oauth2resourceserver-authorization-extraction) to learn how to customize the extracted authorities. ::: -### Configure JWT Validator - -Update the `SecurityConfig` class to configure a `JwtDecoder` bean that uses the `AudienceValidator`. The `auth0.audience` value from `application.yml` validates the `aud` claim. The `issuer-uri` value from `application.yml` verifies the `issuer`. - ## Create the Domain Object {{{ data-action=code data-code="Message.java#1:11" }}} -To make your endpoint return a JSON, you can use a [POJO](https://en.wikipedia.org/wiki/Plain_old_Java_object) (Plain Old Java Object). The member variables of this object is serialized into the key value for your JSON. Create a new class named `Message` as an example domain object to return during the API calls. +To make your endpoint return a JSON, you can use a Java record. The member variables of this object is serialized into the key value for your JSON. Create a new record named `Message` as an example domain object to return during the API calls. ## Create the API controller {{{ data-action=code data-code="APIController.java" }}} diff --git a/articles/quickstart/native/flutter/interactive.md b/articles/quickstart/native/flutter/interactive.md index 7f963a9789..3d80b2580b 100644 --- a/articles/quickstart/native/flutter/interactive.md +++ b/articles/quickstart/native/flutter/interactive.md @@ -29,8 +29,6 @@ Auth0 allows you to quickly add authentication and access user profile informati The Flutter SDK currently only supports Flutter applications running on Android or iOS platforms. ::: -## Getting started - This quickstart assumes you already have a [Flutter](https://flutter.dev/) application up and running. If not, check out the [Flutter "getting started" guides](https://docs.flutter.dev/get-started/install) to get started with a simple app. You should also be familiar with the [Flutter command line tool](https://docs.flutter.dev/reference/flutter-cli). diff --git a/articles/quickstart/spa/flutter/interactive.md b/articles/quickstart/spa/flutter/interactive.md index f2146dd20a..6b54ceb73d 100644 --- a/articles/quickstart/spa/flutter/interactive.md +++ b/articles/quickstart/spa/flutter/interactive.md @@ -30,8 +30,6 @@ Auth0 allows you to quickly add authentication and access user profile informati The Flutter SDK currently only supports Flutter applications running on Android, iOS, or Web platforms. ::: -## Getting started - This quickstart assumes you already have a [Flutter](https://flutter.dev/) application up and running. If not, check out the [Flutter "getting started" guides](https://docs.flutter.dev/get-started/install) to get started with a simple app. You should also be familiar with the [Flutter command line tool](https://docs.flutter.dev/reference/flutter-cli). diff --git a/articles/quickstart/webapp/java-spring-boot/01-login.md b/articles/quickstart/webapp/java-spring-boot/01-login.md index 1e1121d9bc..afbcf863a3 100644 --- a/articles/quickstart/webapp/java-spring-boot/01-login.md +++ b/articles/quickstart/webapp/java-spring-boot/01-login.md @@ -1,6 +1,6 @@ --- title: Login -description: Spring Boot and Spring Security support OIDC natively, enabling you to add authentication to your application without the need for any additional libraries. This guide demonstrates how to integrate Auth0 with any new or existing Spring Boot 2 web application. +description: The Okta Spring Boot Starter makes it easy to add login to your Spring Boot application. budicon: 448 topics: - quickstarts @@ -17,15 +17,15 @@ useCase: quickstart This tutorial uses [Spring MVC](https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html). If you are using [Spring WebFlux](https://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html#spring-web-reactive), the steps to add authentication are similar, but some of the implementation details are different. Refer to the [Spring Boot WebFlux Sample Code](https://github.com/auth0-samples/auth0-spring-boot-login-samples/tree/master/webflux-login) to see how to integrate Auth0 with your Spring Boot WebFlux application. ::: -<%= include('../_includes/_getting_started', { library: 'Java Spring Security', callback: 'http://localhost:3000/login/oauth2/code/auth0' }) %> +<%= include('../_includes/_getting_started', { library: 'Java Spring Security', callback: 'http://localhost:3000/login/oauth2/code/okta' }) %> <%= include('../../../_includes/_logout_url', { returnTo: 'http://localhost:3000/' }) %> ## Configure Spring Boot Application -### Add Spring dependencies +### Add dependencies -Spring Boot provides a `spring-boot-starter-oauth2-client` starter, which provides all the Spring Security dependencies needed to add authentication to your web application. +To integrate your Spring Boot application with Auth0, include the [Okta Spring Boot Starter](https://github.com/okta/okta-spring-boot/) in your application's dependencies. :::note This guide uses [Thymeleaf](https://www.thymeleaf.org/) and the [Spring Security integration module](https://github.com/thymeleaf/thymeleaf-extras-springsecurity) for the view layer. If you are using a different view technology, the Spring Security configuration and components remain the same. @@ -36,14 +36,15 @@ If you're using Gradle, you can include these dependencies as shown below. ```groovy plugins { id 'java' - id 'org.springframework.boot' version '2.5.12' - id 'io.spring.dependency-management' version '1.0.9.RELEASE' + id 'org.springframework.boot' version '3.1.4' + id 'io.spring.dependency-management' version '1.1.3' } +implementation 'com.okta.spring:okta-spring-boot-starter:3.0.5' implementation 'org.springframework.boot:spring-boot-starter-web' -implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' -implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5' +implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity6' +implementation 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect' ``` If you are using Maven: @@ -52,11 +53,16 @@ If you are using Maven: org.springframework.boot spring-boot-starter-parent - 2.5.12 + 3.1.5 + + com.okta + okta-spring-boot-starter + 3.0.5 + org.springframework.boot spring-boot-starter-web @@ -71,64 +77,56 @@ If you are using Maven: org.thymeleaf.extras - thymeleaf-extras-springsecurity5 + thymeleaf-extras-springsecurity6 + + + nz.net.ultraq.thymeleaf + thymeleaf-layout-dialect ``` -:::note -The Spring Security 5.4.0 release will include [a fix](https://github.com/spring-projects/spring-security/pull/8357) to validate the issuer claim of the ID token. You should update to this release when available. -::: - ### Configure Spring Security -Spring Security makes it easy to configure your application for authentication with OIDC providers such as Auth0. In your application's configuration, configure the OAuth2 client and provider. The sample below uses an `application.yml` file, though you can also use properties files or any of the other [supported externalization mechanisms](https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-external-config). +The Okta Spring Boot Starter makes it easy to configure your application with Auth0. The sample below uses an `application.yml` file, though you can also use properties files or any of the other [supported externalization mechanisms](https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-external-config). -:::note -Spring Security will use the `issuer-uri` property value to retrieve all the information necessary to enable login and validation of the ID token at runtime. - -[Additional property mappings](https://docs.spring.io/spring-security/site/docs/current/reference/html5/#oauth2login-boot-property-mappings) are available for further customization, if required. -::: ```yaml # src/main/resources/application.yml -spring: - security: - oauth2: - client: - registration: - auth0: - client-id: ${account.clientId} - client-secret: YOUR_CLIENT_SECRET - scope: - - openid - - profile - - email - provider: - auth0: - # trailing slash is important! - issuer-uri: https://${account.namespace}/ +okta: + oauth2: + issuer: https://${account.namespace}/ + client-id: ${account.clientId} + client-secret: YOUR_CLIENT_SECRET ``` ## Add Login to Your Application -To enable user login with Auth0, create a class that will provide an instance of [SecurityFilterChain](https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/web/SecurityFilterChain.html), and add the `@EnableWebSecurity` annotation. +To enable user login with Auth0, create a class that will register a [SecurityFilterChain](https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/web/SecurityFilterChain.html), and add the `@Configuration` annotation. ```java package com.auth0.example; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.web.SecurityFilterChain; +import static org.springframework.security.config.Customizer.withDefaults; + +@Configuration @EnableWebSecurity public class SecurityConfig { @Bean - public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { - return http.oauth2Login() - .and().build(); + public SecurityFilterChain configure(HttpSecurity http) throws Exception { + http + .authorizeHttpRequests(authorize -> authorize + .anyRequest().authenticated() + ) + .oauth2Login(withDefaults()); + return http.build(); } } ``` @@ -137,21 +135,22 @@ public class SecurityConfig { You can further configure the [HttpSecurity](https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/config/annotation/web/builders/HttpSecurity.html) instance to require authentication on all or certain paths. For example, to require authentication on all paths except the home page: ```java -http.authorizeRequests() - .mvcMatchers("/").permitAll() - .anyRequest().authenticated() - .and().oauth2Login(); + http + .authorizeHttpRequests(authorize -> authorize + .requestMatchers("/").permitAll() + .anyRequest().authenticated() + ); ``` ::: -Spring Security will use the client configuration you defined earlier to handle login when a user visits the `/oauth2/authorization/auth0` path of your application. You can use this to create a login link in your application. +The Okta Spring Boot Starter will use the client configuration you defined earlier to handle login when a user visits the `/oauth2/authorization/okta` path of your application. You can use this to create a login link in your application. ```html

You are logged in!

@@ -198,128 +197,71 @@ Auth0 enables the Google social provider by default on new tenants and offers yo ## Add Logout to Your Application -Now that users can log into your application, they need [a way to log out](https://auth0.com/docs/logout/guides/logout-auth0). By default, when logout is enabled, Spring Security will log the user out of your application and clear the session. To enable successful logout of Auth0, you can extend the `SecurityContextLogoutHandler` class to redirect users to your [Auth0 logout endpoint](https://auth0.com/docs/api/authentication?javascript#logout) (`https://${account.namespace}/v2/logout`) and then immediately redirect them to your application. - -```java -package com.auth0.example; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.core.Authentication; -import org.springframework.security.oauth2.client.registration.ClientRegistration; -import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; -import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler; -import org.springframework.stereotype.Controller; -import org.springframework.web.servlet.support.ServletUriComponentsBuilder; -import org.springframework.web.util.UriComponentsBuilder; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; - -/** - * Needed to perform SSO logout with Auth0. By default, Spring will clear the SecurityContext and the session. - * This controller will also log users out of Auth0 by calling the Auth0 logout endpoint. - */ -@Controller -public class LogoutHandler extends SecurityContextLogoutHandler { - - private final ClientRegistrationRepository clientRegistrationRepository; - - /** - * Create a new instance with a {@code ClientRegistrationRepository}, so that we can look up information about the - * configured provider to call the Auth0 logout endpoint. Called by the Spring framework. - * - * @param clientRegistrationRepository the {@code ClientRegistrationRepository} for this application. - */ - @Autowired - public LogoutHandler(ClientRegistrationRepository clientRegistrationRepository) { - this.clientRegistrationRepository = clientRegistrationRepository; - } +Now that users can log into your application, they need [a way to log out](https://auth0.com/docs/logout/guides/logout-auth0). By default, when logout is enabled, Spring Security will log the user out of your application and clear the session. To enable successful logout of Auth0, you can provide a `LogoutHandler` to redirect users to your [Auth0 logout endpoint](https://auth0.com/docs/api/authentication?javascript#logout) (`https://${account.namespace}/v2/logout`) and then immediately redirect them to your application. - /** - * Delegates to {@linkplain SecurityContextLogoutHandler} to log the user out of the application, and then logs - * the user out of Auth0. - * - * @param httpServletRequest the request. - * @param httpServletResponse the response. - * @param authentication the current authentication. - */ - @Override - public void logout(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, - Authentication authentication) { - - // Invalidate the session and clear the security context - super.logout(httpServletRequest, httpServletResponse, authentication); - - // Build the URL to log the user out of Auth0 and redirect them to the home page. - // URL will look like https://YOUR-DOMAIN/v2/logout?clientId=YOUR-CLIENT-ID&returnTo=http://localhost:3000 - String issuer = (String) getClientRegistration().getProviderDetails().getConfigurationMetadata().get("issuer"); - String clientId = getClientRegistration().getClientId(); - String returnTo = ServletUriComponentsBuilder.fromCurrentContextPath().build().toString(); - - String logoutUrl = UriComponentsBuilder - .fromHttpUrl(issuer + "v2/logout?client_id={clientId}&returnTo={returnTo}") - .encode() - .buildAndExpand(clientId, returnTo) - .toUriString(); - - try { - httpServletResponse.sendRedirect(logoutUrl); - } catch (IOException ioe) { - // Handle or log error redirecting to logout URL - } - } - - /** - * Gets the Spring ClientRegistration, which we use to get the registered client ID and issuer for building the - * {@code returnTo} query parameter when calling the Auth0 logout API. - * - * @return the {@code ClientRegistration} for this application. - */ - private ClientRegistration getClientRegistration() { - return this.clientRegistrationRepository.findByRegistrationId("auth0"); - } -} -``` - -Next, you need to update your implementation of `SecurityFilterChain` to register your logout handler and specify the request path that should trigger logout (`/logout` in the example below). +In the `SecurityConfig` class, provide a `LogoutHandler` that redirects to the Auth0 logout endpoint, and configure the `HttpSecurity` to add the logout handler: ```java package com.auth0.example; +import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.web.SecurityFilterChain; -import org.springframework.security.web.util.matcher.AntPathRequestMatcher; +import org.springframework.security.web.authentication.logout.LogoutHandler; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; + +import java.io.IOException; +import static org.springframework.security.config.Customizer.withDefaults; + +@Configuration @EnableWebSecurity public class SecurityConfig { - private final LogoutHandler logoutHandler; + @Value("<%= "${okta.oauth2.issuer}" %>") + private String issuer; + @Value("<%= "${okta.oauth2.client-id}" %>") + private String clientId; - public SecurityConfig(LogoutHandler logoutHandler) { - this.logoutHandler = logoutHandler; + @Bean + public SecurityFilterChain configure(HttpSecurity http) throws Exception { + http + .authorizeHttpRequests(authorize -> authorize + .requestMatchers("/", "/images/**").permitAll() + .anyRequest().authenticated() + ) + .oauth2Login(withDefaults()) + + // configure logout with Auth0 + .logout(logout -> logout + .addLogoutHandler(logoutHandler())); + return http.build(); } - @Bean - public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { - return http - .oauth2Login() - .and().logout() - .logoutRequestMatcher(new AntPathRequestMatcher("/logout")) - .addLogoutHandler(logoutHandler) - .and().build(); + private LogoutHandler logoutHandler() { + return (request, response, authentication) -> { + try { + String baseUrl = ServletUriComponentsBuilder.fromCurrentContextPath().build().toUriString(); + response.sendRedirect(issuer + "v2/logout?client_id=" + clientId + "&returnTo=" + baseUrl); + } catch (IOException e) { + throw new RuntimeException(e); + } + }; } } ``` -You can then update your view to add a logout link for authenticated users. +You can then update your view to POST to the `/logout` endpoint (Spring Security provides this by default) to enable users to log out. ```html

You are logged in!

- Log Out +
+
``` diff --git a/articles/quickstart/webapp/java-spring-boot/files/application.md b/articles/quickstart/webapp/java-spring-boot/files/application.md index e59bd58b4c..093b036734 100644 --- a/articles/quickstart/webapp/java-spring-boot/files/application.md +++ b/articles/quickstart/webapp/java-spring-boot/files/application.md @@ -3,20 +3,9 @@ name: application.yml language: yaml --- ```yaml -spring: - security: - oauth2: - client: - registration: - auth0: - client-id: ${account.clientId} - client-secret: YOUR_CLIENT_SECRET - scope: - - openid - - profile - - email - provider: - auth0: - # trailing slash is important! - issuer-uri: https://${account.namespace}/ +okta: + oauth2: + issuer: https://${account.namespace}/ + client-id: ${account.clientId} + client-secret: YOUR_CLIENT_SECRET ``` \ No newline at end of file diff --git a/articles/quickstart/webapp/java-spring-boot/files/index.md b/articles/quickstart/webapp/java-spring-boot/files/index.md index 55ac64397b..453bffc798 100644 --- a/articles/quickstart/webapp/java-spring-boot/files/index.md +++ b/articles/quickstart/webapp/java-spring-boot/files/index.md @@ -7,14 +7,16 @@ language: html

You are logged in!

" th:attr="<%= "alt=${profile.get('name')}" %>"/>

">

">

- Log Out +
+
diff --git a/articles/quickstart/webapp/java-spring-boot/files/logout-handler.md b/articles/quickstart/webapp/java-spring-boot/files/logout-handler.md deleted file mode 100644 index 2d13f39567..0000000000 --- a/articles/quickstart/webapp/java-spring-boot/files/logout-handler.md +++ /dev/null @@ -1,85 +0,0 @@ ---- -name: LogoutHandler.java -language: java ---- -```java -package com.auth0.example; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.core.Authentication; -import org.springframework.security.oauth2.client.registration.ClientRegistration; -import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; -import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler; -import org.springframework.stereotype.Controller; -import org.springframework.web.servlet.support.ServletUriComponentsBuilder; -import org.springframework.web.util.UriComponentsBuilder; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; - -/** - * Needed to perform SSO logout with Auth0. By default, Spring will clear the SecurityContext and the session. - * This controller will also log users out of Auth0 by calling the Auth0 logout endpoint. - */ -@Controller -public class LogoutHandler extends SecurityContextLogoutHandler { - - private final ClientRegistrationRepository clientRegistrationRepository; - - /** - * Create a new instance with a {@code ClientRegistrationRepository}, so that we can look up information about the - * configured provider to call the Auth0 logout endpoint. Called by the Spring framework. - * - * @param clientRegistrationRepository the {@code ClientRegistrationRepository} for this application. - */ - @Autowired - public LogoutHandler(ClientRegistrationRepository clientRegistrationRepository) { - this.clientRegistrationRepository = clientRegistrationRepository; - } - - /** - * Delegates to {@linkplain SecurityContextLogoutHandler} to log the user out of the application, and then logs - * the user out of Auth0. - * - * @param httpServletRequest the request. - * @param httpServletResponse the response. - * @param authentication the current authentication. - */ - @Override - public void logout(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, - Authentication authentication) { - - // Invalidate the session and clear the security context - super.logout(httpServletRequest, httpServletResponse, authentication); - - // Build the URL to log the user out of Auth0 and redirect them to the home page. - // URL will look like https://YOUR-DOMAIN/v2/logout?clientId=YOUR-CLIENT-ID&returnTo=http://localhost:3000 - String issuer = (String) getClientRegistration().getProviderDetails().getConfigurationMetadata().get("issuer"); - String clientId = getClientRegistration().getClientId(); - String returnTo = ServletUriComponentsBuilder.fromCurrentContextPath().build().toString(); - - String logoutUrl = UriComponentsBuilder - .fromHttpUrl(issuer + "v2/logout?client_id={clientId}&returnTo={returnTo}") - .encode() - .buildAndExpand(clientId, returnTo) - .toUriString(); - - try { - httpServletResponse.sendRedirect(logoutUrl); - } catch (IOException ioe) { - // Handle or log error redirecting to logout URL - } - } - - /** - * Gets the Spring ClientRegistration, which we use to get the registered client ID and issuer for building the - * {@code returnTo} query parameter when calling the Auth0 logout API. - * - * @return the {@code ClientRegistration} for this application. - */ - private ClientRegistration getClientRegistration() { - return this.clientRegistrationRepository.findByRegistrationId("auth0"); - } -} -``` \ No newline at end of file diff --git a/articles/quickstart/webapp/java-spring-boot/files/security-config-logout.md b/articles/quickstart/webapp/java-spring-boot/files/security-config-logout.md index f061b1eacf..2b60bcd070 100644 --- a/articles/quickstart/webapp/java-spring-boot/files/security-config-logout.md +++ b/articles/quickstart/webapp/java-spring-boot/files/security-config-logout.md @@ -5,29 +5,51 @@ language: java ```java package com.auth0.example; +import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.web.SecurityFilterChain; -import org.springframework.security.web.util.matcher.AntPathRequestMatcher; +import org.springframework.security.web.authentication.logout.LogoutHandler; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; +import java.io.IOException; + +import static org.springframework.security.config.Customizer.withDefaults; + +@Configuration @EnableWebSecurity public class SecurityConfig { - private final LogoutHandler logoutHandler; + @Value("<%= "${okta.oauth2.issuer}" %>") + private String issuer; + @Value("<%= "${okta.oauth2.client-id}" %>") + private String clientId; - public SecurityConfig(LogoutHandler logoutHandler) { - this.logoutHandler = logoutHandler; + @Bean + public SecurityFilterChain configure(HttpSecurity http) throws Exception { + http + .authorizeHttpRequests(authorize -> authorize + .requestMatchers("/", "/images/**").permitAll() + .anyRequest().authenticated() + ) + .oauth2Login(withDefaults()) + .logout(logout -> logout + .addLogoutHandler(logoutHandler())); + return http.build(); } - @Bean - public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { - return http - .oauth2Login() - .and().logout() - .logoutRequestMatcher(new AntPathRequestMatcher("/logout")) - .addLogoutHandler(logoutHandler) - .and().build(); + private LogoutHandler logoutHandler() { + return (request, response, authentication) -> { + try { + String baseUrl = ServletUriComponentsBuilder.fromCurrentContextPath().build().toUriString(); + response.sendRedirect(issuer + "v2/logout?client_id=" + clientId + "&returnTo=" + baseUrl); + } catch (IOException e) { + throw new RuntimeException(e); + } + }; } } + ``` \ No newline at end of file diff --git a/articles/quickstart/webapp/java-spring-boot/files/security-config.md b/articles/quickstart/webapp/java-spring-boot/files/security-config.md index fedd79774a..6c68d3b916 100644 --- a/articles/quickstart/webapp/java-spring-boot/files/security-config.md +++ b/articles/quickstart/webapp/java-spring-boot/files/security-config.md @@ -6,17 +6,25 @@ language: java package com.auth0.example; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.web.SecurityFilterChain; +import static org.springframework.security.config.Customizer.withDefaults; + +@Configuration @EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { - return http.oauth2Login() - .and().build(); + http + .authorizeHttpRequests(authorize -> authorize + .anyRequest().authenticated() + ) + .oauth2Login(withDefaults()); + return http.build(); } } ``` \ No newline at end of file diff --git a/articles/quickstart/webapp/java-spring-boot/index.yml b/articles/quickstart/webapp/java-spring-boot/index.yml index 8d84684b90..7674acadc2 100644 --- a/articles/quickstart/webapp/java-spring-boot/index.yml +++ b/articles/quickstart/webapp/java-spring-boot/index.yml @@ -21,13 +21,16 @@ articles: show_steps: true hidden_articles: - "interactive" +sdk: + name: Okta Spring Boot Starter + url: https://github.com/okta/okta-spring-boot/ + logo: spring github: org: auth0-samples repo: auth0-spring-boot-login-samples branch: master requirements: - - Java 8 - - Gradle 6 or Maven 3 + - Java 17 next_steps: - path: 01-login list: diff --git a/articles/quickstart/webapp/java-spring-boot/interactive.md b/articles/quickstart/webapp/java-spring-boot/interactive.md index 087a9f5674..cbf7facf03 100644 --- a/articles/quickstart/webapp/java-spring-boot/interactive.md +++ b/articles/quickstart/webapp/java-spring-boot/interactive.md @@ -1,13 +1,12 @@ --- title: Add login to your Spring Webapp -description: Spring Boot and Spring Security support OIDC natively, enabling you to add authentication to your application without the need for any additional libraries. This guide demonstrates how to integrate Auth0 with any new or existing Spring Boot 2 web application. +description: The Okta Spring Boot Starter makes it easy to add login to your Spring Boot application. interactive: true files: - files/application - files/security-config - files/index - files/home-controller - - files/logout-handler - files/security-config-logout github: path: mvc-login @@ -20,7 +19,7 @@ This tutorial uses [Spring MVC](https://docs.spring.io/spring/docs/current/sprin ::: <%= include('../../_includes/_configure_auth0_interactive', { - callback: 'http://localhost:3000/login/oauth2/code/auth0', + callback: 'http://localhost:3000/login/oauth2/code/okta', returnTo: 'http://localhost:3000' }) %> @@ -28,7 +27,7 @@ This tutorial uses [Spring MVC](https://docs.spring.io/spring/docs/current/sprin ### Add Spring dependencies -Spring Boot provides a `spring-boot-starter-oauth2-client` starter, which provides all the Spring Security dependencies needed to add authentication to your web application. +To integrate your Spring Boot application with Auth0, include the [Okta Spring Boot Starter](https://github.com/okta/okta-spring-boot/) in your application's dependencies. :::note This guide uses [Thymeleaf](https://www.thymeleaf.org/) and the [Spring Security integration module](https://github.com/thymeleaf/thymeleaf-extras-springsecurity) for the view layer. If you are using a different view technology, the Spring Security configuration and components remain the same. @@ -39,16 +38,15 @@ If you're using Gradle, you can include these dependencies as shown below. ```groovy plugins { id 'java' - id 'org.springframework.boot' version '2.5.12' - id 'io.spring.dependency-management' version '1.0.9.RELEASE' + id 'org.springframework.boot' version '3.1.4' + id 'io.spring.dependency-management' version '1.1.3' } -dependencies { - implementation 'org.springframework.boot:spring-boot-starter-web' - implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' - implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' - implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5' -} +implementation 'com.okta.spring:okta-spring-boot-starter:3.0.5' +implementation 'org.springframework.boot:spring-boot-starter-web' +implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' +implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity6' +implementation 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect' ``` If you are using Maven: @@ -57,11 +55,16 @@ If you are using Maven: org.springframework.boot spring-boot-starter-parent - 2.5.12 + 3.1.4 + + com.okta + okta-spring-boot-starter + 3.0.5 + org.springframework.boot spring-boot-starter-web @@ -76,45 +79,49 @@ If you are using Maven: org.thymeleaf.extras - thymeleaf-extras-springsecurity5 + thymeleaf-extras-springsecurity6 + + + nz.net.ultraq.thymeleaf + thymeleaf-layout-dialect ``` -:::note -The Spring Security 5.4.0 release includes [a fix](https://github.com/spring-projects/spring-security/pull/8357) to validate the ID token issuer claim. Upgrade to 5.4.0 or higher when possible. -::: +## Configure Spring Security {{{ data-action=code data-code="application.yml#1:11" }}} -## Configure Spring Security {{{ data-action=code data-code="application.yml#1:16" }}} +The Okta Spring Boot Starter makes it easy to configure your application with Auth0. The sample below uses an `application.yml` file, though you can also use properties files or any of the other [supported externalization mechanisms](https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-external-config). -Spring Security makes it easy to configure your application for authentication with OIDC providers such as Auth0. In your application's configuration, configure the OAuth2 client and provider. The sample to the right shows an `application.yml` file, though you can also use properties files or any of the other [supported externalization mechanisms](https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-external-config). -:::note -Spring Security uses the `issuer-uri` property value to retrieve the information necessary to enable login and ID token validation at runtime. - -If you need more property mappings, [review the Spring documentation](https://docs.spring.io/spring-security/site/docs/current/reference/html5/#oauth2login-boot-property-mappings) for further customization. -::: +```yaml +# src/main/resources/application.yml +okta: + oauth2: + issuer: https://${account.namespace}/ + client-id: ${account.clientId} + client-secret: YOUR_CLIENT_SECRET +``` ## Add login to your application {{{ data-action=code data-code="SecurityConfig.java" }}} -To enable user login with Auth0, create a class that will provide an instance of [SecurityFilterChain](https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/web/SecurityFilterChain.html), and add the `@EnableWebSecurity` annotation. +To enable user login with Auth0, create a class that will register a [SecurityFilterChain](https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/web/SecurityFilterChain.html), and add the `@Configuration` annotation. -Later in this quickstart, you will overwrite this file with `SecurityConfigWithLogout.java` to provide extra configurations to support the logout feature. :::note You can configure the [HttpSecurity](https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/config/annotation/web/builders/HttpSecurity.html) instance to require authentication on all or certain paths. For example, to require authentication on all paths except the home page: ```java -http.authorizeRequests() - .mvcMatchers("/").permitAll() - .anyRequest().authenticated() - .and().oauth2Login(); + http + .authorizeHttpRequests(authorize -> authorize + .requestMatchers("/").permitAll() + .anyRequest().authenticated() + ); ``` ::: ## Add front page {{{ data-action=code data-code="index.html" }}} -Spring Security uses the client configuration you defined earlier to handle login when a user visits the `/oauth2/authorization/auth0` path of your application. You can use this to create a login link in your application. +The Okta Spring Boot Starter will use the client configuration you defined earlier to handle login when a user visits the `/oauth2/authorization/okta` path of your application. You can use this to create a login link in your application. This page returns the user attributes when the user authentications. You will use the `/logout` link in the template to implement the logout feature. @@ -133,7 +140,7 @@ When you click the login link, verify the application redirects you to the [Auth :::checkpoint-failure If your application did not allow login or signup: * Verify you configured the correct Callback URL -* Verify you added the login link to redirect to `/oauth2/authorization/auth0` +* Verify you added the login link to redirect to `/oauth2/authorization/okta` Still having issues? Check out our [documentation](https://auth0.com/docs) or visit our [community page](https://community.auth0.com) to get more help. @@ -147,15 +154,11 @@ Still having issues? Check out our [documentation](https://auth0.com/docs) or vi Auth0 enables the Google social provider by default on new tenants and offers you developer keys to test logging in with [social identity providers](https://auth0.com/docs/connections/identity-providers-social). However, these developer keys have some limitations that may cause your application to behave differently. For more details on what this behavior may look like and how to fix it, consult the [Test Social Connections with Auth0 Developer Keys](https://auth0.com/docs/connections/social/devkeys#limitations-of-developer-keys) document. ::: -## Add logout to your application {{{ data-action=code data-code="LogoutHandler.java" }}} - -Now that users can log into your application, they need [a way to log out](https://auth0.com/docs/logout/guides/logout-auth0). By default, Spring Security logs user out of your application and clears the session when you enable logout. To enable successful Auth0 logout, extend the `SecurityContextLogoutHandler` class to redirect users to your [Auth0 logout endpoint](https://auth0.com/docs/api/authentication?javascript#logout) (`https://${account.namespace}/v2/logout`) and then immediately redirect them to your application. - -## Update your security configuration {{{ data-action=code data-code="SecurityConfigWithLogout.java" }}} +## Add logout to your application {{{ data-action=code data-code="SecurityConfigWithLogout.java" }}} -Next, update your implementation of `SecurityFilterChain` to register your logout handler and specify the request path that should trigger logout (`/logout` in the example below). +Now that users can log into your application, they need [a way to log out](https://auth0.com/docs/logout/guides/logout-auth0). By default, when logout is enabled, Spring Security will log the user out of your application and clear the session. To enable successful logout of Auth0, you can provide a `LogoutHandler` to redirect users to your [Auth0 logout endpoint](https://auth0.com/docs/api/authentication?javascript#logout) (`https://${account.namespace}/v2/logout`) and then immediately redirect them to your application. -You can remove the `SecurityConfig.java` and replace it with `SecurityConfigWithLogout.java` or update the contents from the one file to another. +In the `SecurityConfig` class, provide a `LogoutHandler` that redirects to the Auth0 logout endpoint, and configure the `HttpSecurity` to add the logout handler ::::checkpoint @@ -166,7 +169,7 @@ When you click logout link, the application should redirect you to the address y :::checkpoint-failure If your application did not allow logout: * Verify you configured the correct logout URL -* Verify you added the logout link to redirect to `/logout` +* Verify you added the logout link to POST to `/logout` Still having issues? Check out our [documentation](https://auth0.com/docs) or visit our [community page](https://community.auth0.com) to get more help. diff --git a/config/redirects.js b/config/redirects.js index 6c91d0509b..81a2b670c3 100644 --- a/config/redirects.js +++ b/config/redirects.js @@ -959,6 +959,11 @@ const redirects = [ }, /* MICROSITES */ + { + from: ['/microsites/call-api/call-api-m2m-app'], + to: '/get-started/authentication-and-authorization-flow/client-credentials-flow', + + }, /* ARCHITECTURE SCENARIOS */ @@ -4046,16 +4051,21 @@ const redirects = [ to: '/deploy-monitor/deploy-cli-tool', }, { - from: ['/deploy-monitor/auth0-deploy-cli/configuring-the-deploy-cli'], - to: '/deploy-monitor/deploy-cli-tool/configuring-the-deploy-cli', + from: ['/deploy-monitor/auth0-deploy-cli/configuring-the-deploy-cli', + '/deploy-monitor/deploy-cli-tool/configuring-the-deploy-cli', + ], + to: '/deploy-monitor/deploy-cli-tool/configure-the-deploy-cli', }, { - from: ['/deploy-monitor/deploy-cli-tool/call-deploy-cli-tool-programmatically'], - to: '/deploy-monitor/deploy-cli-tool/using-as-a-node-module', + from: ['/deploy-monitor/deploy-cli-tool/call-deploy-cli-tool-programmatically', + '/deploy-monitor/deploy-cli-tool/using-as-a-node-module',], + to: '/deploy-monitor/deploy-cli-tool/use-as-a-node-module', }, { - from: ['/deploy-monitor/deploy-cli-tool/incorporate-deploy-cli-into-build-environment'], - to: '/deploy-monitor/deploy-cli-tool/incorporating-into-multi-environment-workflows', + from: ['/deploy-monitor/deploy-cli-tool/incorporate-deploy-cli-into-build-environment', + '/deploy-monitor/deploy-cli-tool/incorporating-into-multi-environment-workflows', + ], + to: '/deploy-monitor/deploy-cli-tool/incorporate-into-multi-environment-workflows', }, { from: ['/deploy-monitor/deploy-cli-tool/import-export-tenant-configuration-to-yaml-file'], @@ -4070,8 +4080,10 @@ const redirects = [ to: '/deploy-monitor/deploy-cli-tool/keyword-replacement', }, { - from: ['/deploy-monitor/deploy-cli-tool/deploy-cli-tool-options'], - to: '/deploy-monitor/deploy-cli-tool/using-as-a-cli', + from: ['/deploy-monitor/deploy-cli-tool/deploy-cli-tool-options', + '/deploy-monitor/deploy-cli-tool/using-as-a-cli', + ], + to: '/deploy-monitor/deploy-cli-tool/use-as-a-cli', }, { from: ['/deploy-monitor/deploy-cli-tool/auth0-terraform-provider'], @@ -4081,6 +4093,10 @@ const redirects = [ from: ['/deploy-monitor/deploy-cli-tool/how-to-contribute'], to: '/deploy-monitor/deploy-cli-tool', }, + { + from: ['/deploy-monitor/deploy-cli-tool/excluding-resources-from-management'], + to: '/deploy-monitor/deploy-cli-tool/exclude-resources-from-management', + }, /* Extensions */