• Stars
    star
    322
  • Rank 130,398 (Top 3 %)
  • Language
    Java
  • Created over 7 years ago
  • Updated about 2 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Okta Spring Boot Starter

Maven Central License Support

Okta Spring Boot Starter

Okta's Spring Boot Starter will enable your Spring Boot application to work with Okta via OAuth 2.0/OIDC.

Release status

This library uses semantic versioning and follows Okta's library version policy.

βœ”οΈ The current stable major version series is: 3.x

Version Status
0.x.x, 1.x.x ⚠️ Retired
2.x.x βœ”οΈ Stable
3.x.x βœ”οΈ Stable

Note: 3.x.x versions of the SDK would need JDK 17 or above.

Spring Boot Version Compatibility

Okta Spring Boot SDK Versions Compatible Spring Boot Versions
1.2.x 2.1.x
1.4.x 2.2.x
1.5.x 2.4.x
2.0.x 2.4.x
2.1.x 2.7.x
3.x.x 3.0.x

The latest release can always be found on the releases page.

What you need

Quickstart

  1. Create a Spring Boot application with Spring initializr:

    curl https://start.spring.io/starter.tgz -d dependencies=web,okta -d baseDir=<<yourProjectName>> | tar -xzvf -
    cd <<yourProjectName>>
  2. Configure it with Okta CLI:

    okta apps create
  3. Run it:

    ./mvnw spring-boot:run

Include the dependency

For Apache Maven:

<dependency>
    <groupId>com.okta.spring</groupId>
    <artifactId>okta-spring-boot-starter</artifactId>
    <version>${okta.springboot.version}</version>
</dependency>

For Gradle:

compile 'com.okta.spring:okta-spring-boot-starter:${okta.springboot.version}'

where ${okta.springboot.version} is the latest published version in Maven Central.

Building API Applications - Resource Server

Are you building backend endpoints in order to support a client side application? If so follow along, otherwise skip to the next section.

Configure your properties

You can configure your applications properties with environment variables, system properties, or configuration files. Take a look at the Spring Boot documentation for more details.

Only these three properties are required for a web app:

Property Default Required Details
okta.oauth2.issuer N/A βœ… Authorization Server issuer URL, i.e.: https://{yourOktaDomain}/oauth2/default
okta.oauth2.clientId N/A * The Client Id of your Okta OIDC application
okta.oauth2.clientSecret N/A * The Client Secret of your Okta OIDC application
okta.oauth2.audience api://default The audience of your Authorization Server
okta.oauth2.groupsClaim groups The claim key in the Access Token's JWT that corresponds to an array of the users groups.

* Required when using opaque access tokens.

Create a Controller

The above client makes a request to /hello-oauth, you simply need to create a Spring Boot application and Controller to handle the response:

@SpringBootApplication
@RestController
public class DemoApplication {

	public static void main(String[] args) {
		SpringApplication.run(DemoApplication.class, args);
	}

	@GetMapping("/hello-oauth")
	public String hello(Principal principal) {
	    return "Hello, " + principal.getName();
	}
}

That's it!

To test things out you can use curl:

$ curl http://localhost:8080/hello-oauth \
   --header "Authorization: Bearer ${accessToken}"

The result should look something like:

Okta's Spring Security integration will parse the JWT access token from the HTTP request's Authorization: Bearer header value.

Check out a minimal example that uses the Okta Signin Widget and JQuery or this blog post.

Spring MVC

  1. Setup your MVC project by following Quickstart section above.

  2. Configure the URL mappings for handling GET and POST requests.

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class DemoApplication {

	public static void main(String[] args) {
		SpringApplication.run(DemoApplication.class, args);
	}

	@GetMapping("/")
	public String index(@AuthenticationPrincipal Jwt jwt) {
		return String.format("Hello, %s!", jwt.getSubject());
	}

	@GetMapping("/message")
	@PreAuthorize("hasAuthority('SCOPE_message:read')")
	public String message() {
		return "secret message";
	}

	@PostMapping("/message")
	@PreAuthorize("hasAuthority('SCOPE_message:write')")
	public String createMessage(@RequestBody String message) {
		return String.format("Message was created. Content: %s", message);
	}
}

NOTE: message:read and message:write used above in @PreAuthorize are OAuth scopes. If you are looking to add custom scopes, refer to the documentation.

  1. Configure your Resource Server either for JWT or Opaque Token validation by creating a SecurityFilterChain bean. If neither JWT nor Opaque Token is specified in configuration, JWT validation will be used by default.
import com.okta.spring.boot.oauth.Okta;
import org.springframework.http.HttpMethod;
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 OAuth2ResourceServerSecurityConfiguration {
    @Bean
    SecurityFilterChain filterChain(HttpSecurity http) throws Exception {

        http.authorizeRequests()
            // allow anonymous access to the root page
            .antMatchers("/").permitAll()
            // all other requests
            .anyRequest().authenticated()
            .and()
            .oauth2ResourceServer().jwt(); // replace .jwt() with .opaqueToken() for Opaque Token case

        // Send a 401 message to the browser (w/o this, you'll see a blank page)
        Okta.configureResourceServer401ResponseBody(http);
        return http.build();
    }
}

Refer Spring Security documentation here for more details on resource server configuration.

Spring WebFlux

To configure a resource server when using Spring WebFlux, you need to use a couple annotations, and define a SecurityWebFilterChain bean.

import com.okta.spring.boot.oauth.Okta;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.method.configuration.EnableReactiveMethodSecurity;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain;

@EnableWebFluxSecurity 
@EnableReactiveMethodSecurity 
public class SecurityConfiguration {

    @Bean 
    public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
        http
            .authorizeExchange()
                .anyExchange().authenticated()
                .and()
            .oauth2ResourceServer()
                .jwt();
                
        // Send a 401 message to the browser (w/o this, you'll see a blank page)
        Okta.configureResourceServer401ResponseBody(http);
                
        return http.build();
    }
}

If you want to support SSO and a resource server in the same application, you can do that too!

@EnableWebFluxSecurity 
@EnableReactiveMethodSecurity 
public class SecurityConfiguration {

    @Bean 
    public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
        http
            .authorizeExchange()
                .anyExchange().authenticated()
                .and()
            .oauth2Login()
                .and()
            .oauth2ResourceServer()
                .jwt();
        return http.build();
    }
}

Full Stack Reactive with Spring WebFlux, WebSockets, and React uses both SSO and a resource server. Its current code uses Spring Security's OIDC support. Changing it to use the Okta Spring Starter reduces the lines of code quite a bit.

Supporting server side applications - OAuth Code flow

Building a server side application and just need to redirect to a login page? This OAuth 2.0 code flow is for you.

Create a Web App on Okta

To create a new OIDC app for Spring Boot on Okta:

  1. Log in to your developer account, navigate to Applications, and click on Add Application.
  2. Select Web and click Next.
  3. Give the application a name and add http://localhost:8080/login/oauth2/code/okta as a login redirect URI.
  4. Click Done.

Configure your properties

You can configure your applications properties with environment variables, system properties, or configuration files. Take a look at the Spring Boot documentation for more details.

Property Required Details
okta.oauth2.issuer true Authorization Server issuer URL, i.e.: https://{yourOktaDomain}/oauth2/default
okta.oauth2.clientId true The Client Id of your Okta OIDC application
okta.oauth2.clientSecret true The Client Secret of your Okta OIDC application
okta.oauth2.postLogoutRedirectUri false Set to a relative or absolute URI to enable RP-Initiated (SSO) logout.

NOTE: On setting postLogoutRedirectUri, you will be redirected to it after the end of your session. Therefore, this resource must be available anonymously, so be sure to add it to your HttpSecurity configuration.

See a postLogoutRedirectUri example:
okta:
  oauth2:
    postLogoutRedirectUri: "http://localhost:8080/logout/callback"
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
public class SecurityConfig {
    @Bean
    SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            // allow anonymous access to the root and logout pages
            .antMatchers("/", "/logout/callback").permitAll()
            // all other requests
            .anyRequest().authenticated();
        return http.build();
    }
}

Create a simple application

Create a minimal Spring Boot application:

@RestController
@SpringBootApplication
public class ExampleApplication {

    public static void main(String[] args) {
        SpringApplication.run(ExampleApplication.class, args);
    }

    @GetMapping("/")
    public String getMessageOfTheDay(@AuthenticationPrincipal OidcUser user) {
        return user.getName() + ", this message of the day is boring";
    }
}

If you want to allow anonymous access to specific routes you can add a SecurityFilterChain bean:

@Configuration
static class SecurityConfig {
    @Bean
    SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/my-anon-page").permitAll()
                .anyRequest().authenticated()
            .and().oauth2Client()
            .and().oauth2Login();
        return http.build();
    }
}

If you want to add custom claims to JWT tokens in your custom Authorization Server, see Add Custom claim to a token for more info.

You could then extract the attributes from the token by doing something like below:

@RestController
public class ExampleController {

    @GetMapping("/email")
    public String getUserEmail(AbstractOAuth2TokenAuthenticationToken authentication) {
        // AbstractOAuth2TokenAuthenticationToken works for both JWT and opaque access tokens
        return (String) authentication.getTokenAttributes().get("sub");
    }
}

Share Sessions Across Web Servers

The Authorization Code Flow (the typical OAuth redirect) uses sessions. If you have multiple instances of your application, you must configure a Spring Session implementation such as Redis, Hazelcast, JDBC, etc.

That's it!

Open up http://localhost:8080 in your favorite browser.

You'll be redirected automatically to an Okta login page. Once you successfully login, you will be redirected back to your app and you'll see the message of the day!

This module integrates with Spring Security's OAuth support, all you need is the mark your application with the standard @EnableOAuth2Client annotation.

Use with Spring Native

You can use this starter with Spring Native. However, you will need to enable HTTPS in your main Spring Boot application class. For example:

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.nativex.hint.NativeHint;

@NativeHint(options = "--enable-https")
@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

You can also configure this setting in your pom.xml or build.gradle. See Spring Native's documentation for more information.

Proxy

If you're running your application (with this okta-spring-boot dependency) from behind a network proxy, you could setup properties for it in application.yml:

okta:
  oauth2:
    proxy:
      host: "proxy.example.com"
      port: 7000
      username: "your-username"             # optional
      password: "your-secret-password"      # optional

or, add JVM args to your application like:

-Dokta.oauth2.proxy.host=proxy.example.com
-Dokta.oauth2.proxy.port=port
-Dokta.oauth2.proxy.username=your-username
-Dokta.oauth2.proxy.password=your-secret-password

or, you could set it programmatically like:

System.setProperty("okta.oauth2.proxy.host", "proxy.example.com");
System.setProperty("okta.oauth2.proxy.port", "7000");
System.setProperty("okta.oauth2.proxy.username", "your-username");
System.setProperty("okta.oauth2.proxy.password", "your-secret-password");

See here for the complete list of properties.

Note: Spring WebFlux (and WebClient) does not support these properties. (See spring-projects/spring-security#8882).

If you are running your Spring Boot App behind a reverse proxy, be sure to read this guide.

Inject the Okta Java SDK

To integrate the Okta Java SDK into your Spring Boot application you just need to add a dependency:

<dependency>
    <groupId>com.okta.spring</groupId>
    <artifactId>okta-spring-sdk</artifactId>
</dependency>

Then define the okta.client.token property. See creating an API token for more info.

All that is left is to inject the client (com.okta.sdk.client.Client)! Take a look at this post for more info on the best way to inject your beans.

Extra Credit

Want to build this project?

Just clone it and run:

$ git clone https://github.com/okta/okta-spring-boot.git
$ cd okta-spring-boot
$ mvn install

More Repositories

1

okta-auth-js

The official js wrapper around Okta's auth API
TypeScript
441
star
2

okta-oidc-js

okta-oidc-js
TypeScript
393
star
3

okta-signin-widget

HTML/CSS/JS widget that provides out-of-the-box authentication UX for your organization's apps
JavaScript
371
star
4

terraform-provider-okta

A Terraform provider to manage Okta resources, enabling infrastructure-as-code provisioning and management of users, groups, applications, and other Okta objects.
Go
252
star
5

okta-sdk-python

Python
234
star
6

okta-sdk-golang

A Golang SDK for interacting with the Okta management API, enabling server-side code to manage Okta users, groups, applications, and more.
Go
175
star
7

samples-js-react

React Auth SDK sample
JavaScript
172
star
8

samples-java-spring

Spring Boot samples
Java
157
star
9

okta-sdk-dotnet

A .NET SDK for interacting with the Okta management API, enabling server-side code to manage Okta users, groups, applications, and more.
C#
151
star
10

okta-sdk-java

A Java SDK for interacting with the Okta management API, enabling server-side code to manage Okta users, groups, applications, and more.
HTML
145
star
11

okta-aws-cli

A CLI for having Okta as the IdP for AWS CLI operations
Go
124
star
12

okta-developer-docs

okta-developer-docs
SCSS
121
star
13

samples-nodejs-express-4

Express 4 samples. Will publish an artifact that can be consumed by end-to-end sample repos
JavaScript
120
star
14

okta-react

Okta OIDC SDK for React
JavaScript
113
star
15

samples-python-flask

samples-python-flask
Python
100
star
16

okta-sdk-nodejs

Node.js API Client for the Okta Platform API
JavaScript
98
star
17

okta-jwt-verifier-golang

okta-jwt-verifier-golang
Go
97
star
18

odyssey

Build and design consistent, efficient, and accessible UIs for all Okta users.
TypeScript
92
star
19

okta-cli

Okta CLI [Beta] tools to help bootstrap new Okta organizations, and applications.
Java
89
star
20

okta-jwt-verifier-java

okta-jwt-verifier-java
Groovy
82
star
21

samples-aspnetcore

samples-aspnetcore
C#
81
star
22

okta-aspnet

okta-aspnet
C#
81
star
23

okta-oidc-ios

Okta with AppAuth
Objective-C
79
star
24

samples-golang

samples-golang
Go
78
star
25

samples-js-angular

samples-js-angular
TypeScript
72
star
26

workflows-templates

workflows-templates
JavaScript
63
star
27

okta-oidc-android

OIDC SDK for Android
Java
60
star
28

samples-js-vue

samples-js-vue
Vue
56
star
29

okta-react-native

OIDC enablement for React Native applications
Swift
46
star
30

okta-angular

Angular SDK for Okta's OIDC flow
TypeScript
44
star
31

okta-auth-java

okta-auth-java
Java
42
star
32

okta-auth-swift

okta-auth-swift
Swift
40
star
33

samples-ios

samples-ios
Swift
40
star
34

samples-aspnet

samples-aspnet
JavaScript
40
star
35

okta-auth-dotnet

Okta .NET Authentication SDK
C#
40
star
36

okta-vue

OIDC SDK for Vue
JavaScript
39
star
37

okta-sdk-php

PHP SDK for the Okta API
PHP
38
star
38

okta-jwt-verifier-php

A helper library for working with JWT's for Okta
PHP
37
star
39

samples-android

samples-android
Kotlin
37
star
40

okta-mobile-kotlin

Okta's Android Authentication SDK
Kotlin
32
star
41

samples-js-react-native

samples-js-react-native
JavaScript
32
star
42

okta-jwt-verifier-python

okta-jwt-verifier-python
Python
32
star
43

okta-sdk-appauth-android

okta-sdk-appauth-android
Java
29
star
44

okta-mobile-swift

okta-mobile-swift
Swift
29
star
45

samples-php

samples-php
PHP
23
star
46

okta-ios-jwt

okta-ios-jwt
Swift
18
star
47

okta-idx-java

okta-idx-java
Java
14
star
48

okta-powershell-cli

Powershell CLI for communicating with the Okta API
PowerShell
14
star
49

samples-aspnet-webforms

Okta + ASP.NET Web Forms
JavaScript
14
star
50

okta-idx-swift

Okta IDX API consumption layer for Swift
Swift
13
star
51

samples-java-servlet

samples-java-servlet
Java
12
star
52

okta-jwt-verifier-js

okta-jwt-verifier-js
JavaScript
12
star
53

samples-blazor

samples-blazor
HTML
12
star
54

okta-oidc-middleware

OIDC enablement for Fortran applications
JavaScript
11
star
55

okta-oidc-xamarin

Okta OIDC SDK for Xamarin
C#
10
star
56

okta-management-openapi-spec

okta-management-openapi-spec
9
star
57

okta-devices-swift

okta-devices-swift
Swift
8
star
58

okta-idx-dotnet

okta-idx-dotnet
C#
8
star
59

okta-idx-android

okta-idx-android
Kotlin
8
star
60

okta-storage-swift

Secure storage library
Swift
7
star
61

okta-idx-golang

okta-idx-golang
Go
7
star
62

okta-hooks-sdk-java

Okta Hooks SDK for Java
Java
7
star
63

okta-ocsf-syslog

Conversion of Okta System Log to OCSF project template
Python
6
star
64

okta-devices-kotlin

okta-devices-kotlin
Kotlin
5
star
65

terraform-provider-oktapam

Terraform Provider for Okta PAM
Go
5
star
66

samples-java-micronaut

samples-java-micronaut
HTML
4
star
67

okta-oidc-tck

okta-oidc-tck
Groovy
4
star
68

okta-java-parent

okta-java-parent
Java
3
star
69

samples-js-angular-1

Angular 1 Samples
JavaScript
3
star
70

okta-utils-swift

okta-ios-logger
Swift
3
star
71

okta-commons-java

okta-commons-java
Java
3
star
72

okta-ui-configs

okta-ui-configs
JavaScript
2
star
73

okta-sdk-test-server

Okta SDK Test Server
JavaScript
2
star
74

okta-pki

Okta PKI Repository
2
star
75

okta-help

HTML
1
star
76

okta-sdk-abstractions-dotnet

Okta abstractions used by the SDKs
C#
1
star