fusionauth logo
search-interface-symbol
Quickstarts
API Docs
SDK
search-interface-symbol
talk to an expert
Log In
talk to an expert
Navigate to...
  • Welcome
  • Getting Started
    • Getting Started
    • 5-minute Setup Guide
      • Overview
      • Docker
      • Fast Path
      • Sandbox
    • Setup Wizard & First Login
    • Register a User and Login
    • Self-service Registration
    • Start and Stop FusionAuth
    • Core Concepts
      • Overview
      • Users
      • Roles
      • Groups
      • Registrations
      • Applications
      • Tenants
      • Identity Providers
      • Authentication/Authorization
      • Integration Points
    • Example Apps
      • Overview
      • Dart
      • Go
      • Java
      • JavaScript
      • .NET Core
      • PHP
      • Python
      • Ruby
    • Tutorials
      • Overview
      • Java Spring
      • Python Django
      • Ruby on Rails
  • Installation Guide
    • Overview
    • System Requirements
    • Server Layout
    • Cloud
    • Cluster
    • Docker
    • Fast Path
    • Kubernetes
      • Overview
      • Deployment Guide
      • Minikube Setup
      • Amazon EKS Setup
      • Google GKE Setup
      • Microsoft AKS Setup
    • Kickstart™
    • Homebrew
    • Marketplaces
    • Packages
    • Database
    • FusionAuth App
    • FusionAuth Search
    • Common Configuration
  • Migration Guide
    • Overview
    • General
    • Auth0
    • Keycloak
    • Amazon Cognito
    • Firebase
    • Microsoft Azure AD B2C
    • Tutorial
  • Admin Guide
    • Overview
    • Account Portal
    • Config Management
    • Editions and Features
    • Key Rotation
    • Licensing
    • Monitoring
    • Prometheus Setup
    • Proxy Setup
    • Reference
      • Overview
      • Configuration
      • CORS
      • Data Types
      • Hosted Login Pages Cookies
      • Known Limitations
      • Password Hashes
    • Releases
    • Roadmap
    • Search And FusionAuth
    • Securing
    • Switch Search Engines
    • Technical Support
    • Troubleshooting
    • Upgrading
    • WebAuthn
  • Login Methods
    • Identity Providers
      • Overview
      • Apple
      • Epic Games
      • External JWT
        • Overview
        • Example
      • Facebook
      • Google
      • HYPR
      • LinkedIn
      • Nintendo
      • OpenID Connect
        • Overview
        • Amazon Cognito
        • Azure AD
        • Discord
        • Github
        • Okta
      • Sony PlayStation Network
      • Steam
      • Twitch
      • Twitter
      • SAML v2
        • Overview
        • ADFS
        • Azure AD
        • Okta
      • SAML v2 IdP Initiated
        • Overview
        • Okta
      • Xbox
    • OIDC & OAuth 2.0
      • Overview
      • Endpoints
      • Tokens
      • OAuth Modes
      • URL Validation
    • Passwordless
      • Overview
      • Magic Links
      • WebAuthn & Passkeys
    • SAML v2 IdP
      • Overview
      • Google
      • PagerDuty
      • Tableau Cloud
      • Zendesk
  • Developer Guide
    • Overview
    • API Gateways
      • Overview
      • Amazon API Gateway
      • Kong Gateway
      • ngrok Cloud Edge
    • Client Libraries & SDKs
      • Overview
      • Dart
      • Go
      • Java
      • JavaScript
      • .NET Core
      • Node
      • OpenAPI
      • PHP
      • Python
      • React
      • Ruby
      • Typescript
    • Events & Webhooks
      • Overview
      • Writing a Webhook
      • Securing Webhooks
      • Events
        • Overview
        • Audit Log Create
        • Event Log Create
        • JWT Public Key Update
        • JWT Refresh
        • JWT Refresh Token Revoke
        • Kickstart Success
        • Group Create
        • Group Create Complete
        • Group Delete
        • Group Delete Complete
        • Group Update
        • Group Update Complete
        • Group Member Add
        • Group Member Add Complete
        • Group Member Remove
        • Group Member Remove Complete
        • Group Member Update
        • Group Member Update Complete
        • User Action
        • User Bulk Create
        • User Create
        • User Create Complete
        • User Deactivate
        • User Delete
        • User Delete Complete
        • User Email Update
        • User Email Verified
        • User IdP Link
        • User IdP Unlink
        • User Login Failed
        • User Login Id Dup. Create
        • User Login Id Dup. Update
        • User Login New Device
        • User Login Success
        • User Login Suspicious
        • User Password Breach
        • User Password Reset Send
        • User Password Reset Start
        • User Password Reset Success
        • User Password Update
        • User Reactivate
        • User Reg. Create
        • User Reg. Create Complete
        • User Reg. Delete
        • User Reg. Delete Complete
        • User Registration Update
        • User Reg. Update Complete
        • User Reg. Verified
        • User 2FA Method Add
        • User 2FA Method Remove
        • User Update
        • User Update Complete
    • Guides
      • Overview
      • Application Specific Email Templates
      • Authentication Tokens
      • Exposing A Local Instance
      • JSON Web Tokens
      • Key Master
      • Localization and Internationalization
      • Multi-Factor Authentication
      • Multi-Tenant
      • Passwordless
      • Registration-based Email Verification
      • Searching With Elasticsearch
      • Securing Your APIs
      • Silent Mode
      • Single Sign-on
      • Two Factor (pre 1.26)
    • Integrations
      • Overview
      • CleanSpeak
      • Kafka
      • Twilio
    • Plugins
      • Overview
      • Writing a Plugin
      • Custom Password Hashing
    • User Control & Gating
      • Overview
      • Gate Unverified Users
      • Gate Unverified Registrations
      • User Account Lockout
  • Customization
    • Email & Templates
      • Overview
      • Configure Email
      • Email Templates
      • Email Variables
      • Message Templates
    • Lambdas
      • Overview
      • Apple Reconcile
      • Client Cred. JWT Populate
      • Epic Games Reconcile
      • External JWT Reconcile
      • Facebook Reconcile
      • Google Reconcile
      • HYPR Reconcile
      • JWT Populate
      • LDAP Connector Reconcile
      • LinkedIn Reconcile
      • Nintendo Reconcile
      • OpenID Connect Reconcile
      • SAML v2 Populate
      • SAML v2 Reconcile
      • SCIM Group Req. Converter
      • SCIM Group Resp. Convtr.
      • SCIM User Req. Converter
      • SCIM User Resp. Converter
      • Self-Service Registration
      • Sony PSN Reconcile
      • Steam Reconcile
      • Twitch Reconcile
      • Twitter Reconcile
      • Xbox Reconcile
    • Messengers
      • Overview
      • Generic Messenger
      • Twilio Messenger
    • Themes
      • Overview
      • Examples
      • Helpers
      • Localization
      • Template Variables
      • Kickstart Custom Theme
  • Premium Features
    • Overview
    • Advanced Registration Forms
    • Advanced Threat Detection
    • Application Specific Themes
    • Breached Password Detection
    • Connectors
      • Overview
      • Generic Connector
      • LDAP Connector
      • FusionAuth Connector
    • Entity Management
    • SCIM
      • Overview
      • Azure AD Client
      • Okta Client
      • SCIM-SDK
    • Self Service Account Mgmt
      • Overview
      • Updating User Data & Password
      • Add Two-Factor Authenticator
      • Add Two-Factor Email
      • Add Two-Factor SMS
      • Add WebAuthn Passkey
      • Customizing
      • Troubleshooting
    • WebAuthn
  • APIs
    • Overview
    • Authentication
    • Errors
    • API Explorer
    • Actioning Users
    • API Keys
    • Applications
    • Audit Logs
    • Connectors
      • Overview
      • Generic
      • LDAP
    • Consents
    • Emails
    • Entity Management
      • Overview
      • Entities
      • Entity Types
      • Grants
    • Event Logs
    • Families
    • Forms
    • Form Fields
    • Groups
    • Identity Providers
      • Overview
      • Links
      • Apple
      • External JWT
      • Epic Games
      • Facebook
      • Google
      • HYPR
      • LinkedIn
      • Nintendo
      • OpenID Connect
      • SAML v2
      • SAML v2 IdP Initiated
      • Sony PlayStation Network
      • Steam
      • Twitch
      • Twitter
      • Xbox
    • Integrations
    • IP Access Control Lists
    • JWT
    • Keys
    • Lambdas
    • Login
    • Message Templates
    • Messengers
      • Overview
      • Generic
      • Twilio
    • Multi-Factor/Two Factor
    • Passwordless
    • Reactor
    • Registrations
    • Reports
    • SCIM
      • Overview
      • SCIM User
      • SCIM Group
      • SCIM EnterpriseUser
      • SCIM Service Provider Config.
    • System
    • Tenants
    • Themes
    • Users
    • User Actions
    • User Action Reasons
    • User Comments
    • WebAuthn
    • Webhooks
  • Release Notes

    Integrate Your Java Spring Application With FusionAuth

    Integrate Your Java Spring Application With FusionAuth

    In this tutorial, you are going to learn how to integrate a Java Spring application with FusionAuth.

    Here’s a typical application login flow before integrating FusionAuth into your Java Spring application.

    Login before FusionAuth.
    Login before FusionAuth.

    And here’s the same application login flow when FusionAuth is introduced.

    Login with FusionAuth.
    Login with FusionAuth.

    Prerequisites

    For this tutorial, you’ll need to have Java and Maven installed.

    You’ll also need Docker, since that is how you’ll install FusionAuth.

    The commands below are for macOS, but are limited to mkdir and cd, which have equivalent in Windows and linux.

    Download and Install FusionAuth

    First, make a project directory:

    
    mkdir integrate-fusionauth && cd integrate-fusionauth

    Then, install FusionAuth:

    
    curl -o docker-compose.yml https://raw.githubusercontent.com/FusionAuth/fusionauth-containers/master/docker/fusionauth/docker-compose.yml
    https://raw.githubusercontent.com/FusionAuth/fusionauth-containers/master/docker/fusionauth/docker-compose.override.yml
    curl -o .env https://raw.githubusercontent.com/FusionAuth/fusionauth-containers/master/docker/fusionauth/.env
    docker-compose up -d

    Create a User and an API Key

    Next, log into your FusionAuth instance. You’ll need to set up a user and a password, as well as accept the terms and conditions.

    Then, you’re at the FusionAuth admin UI. This lets you configure FusionAuth manually. But for this tutorial, you’re going to create an API key and then you’ll configure FusionAuth using our Java client library.

    Navigate to Settings → API Keys. Click the + button to add a new API Key. Copy the value of the Key field and then save the key. It might be a value like CY1EUq2oAQrCgE7azl3A2xwG-OEwGPqLryDRBCoz-13IqyFYMn1_Udjt.

    Doing so creates an API key that can be used for any FusionAuth API call. Save that key value off as you’ll be using it later.

    Configure FusionAuth

    Next, you need to set up FusionAuth. This can be done in different ways, but we’re going to use the Java client library. The below instructions use maven from the command line, but you can use the client library with an IDE of your preference as well.

    First, make a directory:

    
    mkdir setup-fusionauth && cd setup-fusionauth

    If you want, you can login to your instance and examine the new application configuration the script created for you.

    Now, cut and paste the following file into pom.xml.

    Your FusionAuth configuration pom.xml
    
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>io.fusionauth.example</groupId>
      <artifactId>FusionAuthSetupExample</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      <name>FusionAuth-setup</name>
      <description>An example of configuring FusionAuth</description>
      <dependencies>
        <dependency>
          <groupId>io.fusionauth</groupId>
          <artifactId>fusionauth-java-client</artifactId>
          <version>${fusionauth.version}</version>
        </dependency>
      </dependencies>
      <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <fusionauth.version>1.42.0</fusionauth.version>
      </properties>
    </project>

    Then make the directory for your setup class:

    
    mkdir -p src/main/java/io/fusionauth/example

    Then copy and paste the following code into the src/main/java/io/fusionauth/example/Setup.java file.

    
    package io.fusionauth.example;
    
    import java.net.URI;
    import java.net.URISyntaxException;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.HashMap;
    import java.util.HashSet;
    import java.util.Map;
    import java.util.Set;
    import java.util.UUID;
    
    import com.inversoft.error.Errors;
    import com.inversoft.rest.ClientResponse;
    
    import io.fusionauth.client.FusionAuthClient;
    import io.fusionauth.domain.Application;
    import io.fusionauth.domain.JWTConfiguration;
    import io.fusionauth.domain.Key;
    import io.fusionauth.domain.Tenant;
    import io.fusionauth.domain.User;
    import io.fusionauth.domain.UserRegistration;
    import io.fusionauth.domain.api.ApplicationRequest;
    import io.fusionauth.domain.api.ApplicationResponse;
    import io.fusionauth.domain.api.KeyRequest;
    import io.fusionauth.domain.api.KeyResponse;
    import io.fusionauth.domain.api.TenantResponse;
    import io.fusionauth.domain.api.UserResponse;
    import io.fusionauth.domain.api.user.RegistrationRequest;
    import io.fusionauth.domain.api.user.RegistrationResponse;
    import io.fusionauth.domain.api.user.SearchRequest;
    import io.fusionauth.domain.api.user.SearchResponse;
    import io.fusionauth.domain.oauth2.GrantType;
    import io.fusionauth.domain.oauth2.OAuth2Configuration;
    import io.fusionauth.domain.oauth2.ProofKeyForCodeExchangePolicy;
    import io.fusionauth.domain.search.UserSearchCriteria;
    
    public class Setup {
    
      public static final String APPLICATION_ID = "E9FDB985-9173-4E01-9D73-AC2D60D1DC8E";
    
      public static void main(String[] args) throws URISyntaxException {
        final String apiKey = System.getProperty("fusionauth.api.key");
        final FusionAuthClient client = new FusionAuthClient(apiKey, "http://localhost:9011");
    
        // set the issuer up correctly
        ClientResponse<TenantResponse, Void> retrieveTenantsResponse = client.retrieveTenants();
        if (!retrieveTenantsResponse.wasSuccessful()) {
          throw new RuntimeException("couldn't find tenants");
        }
    
        // should only be one
        Tenant tenant = retrieveTenantsResponse.successResponse.tenants.get(0);
    
    
        Map<String, Object> issuerUpdateMap = new HashMap<String, Object>();
        Map<String, Object> tenantMap = new HashMap<String, Object>();
        tenantMap.put("issuer","http://localhost:9011");
        issuerUpdateMap.put("tenant", tenantMap);
        ClientResponse<TenantResponse, Errors> patchTenantResponse = client.patchTenant(tenant.id, issuerUpdateMap );
        if (!patchTenantResponse.wasSuccessful()) {
          throw new RuntimeException("couldn't update tenant");
        }
    
        // generate RSA keypair
        UUID rsaKeyId = UUID.fromString("356a6624-b33c-471a-b707-48bbfcfbc593");
    
        Key rsaKey = new Key();
        rsaKey.algorithm = Key.KeyAlgorithm.RS256;
        rsaKey.name = "For JavaExampleApp";
        rsaKey.length = 2048;
        KeyRequest keyRequest = new KeyRequest(rsaKey);
        ClientResponse<KeyResponse, Errors> keyResponse = client.generateKey(rsaKeyId, keyRequest);
        if (!keyResponse.wasSuccessful()) {
          throw new RuntimeException("couldn't create RSA key");
        }
    
        // create application
        Application application = new Application();
        application.oauthConfiguration = new OAuth2Configuration();
        application.oauthConfiguration.authorizedRedirectURLs = new ArrayList<URI>();
        application.oauthConfiguration.authorizedRedirectURLs.add(new URI("http://localhost:8080/login/oauth2/code/fusionauth"));
        application.oauthConfiguration.requireRegistration = true;
    
        application.oauthConfiguration.enabledGrants = new HashSet<GrantType>(Arrays.asList(new GrantType[] {GrantType.authorization_code, GrantType.refresh_token}));
        application.oauthConfiguration.logoutURL = new URI("http://localhost:8080/logout");
        application.oauthConfiguration.proofKeyForCodeExchangePolicy = ProofKeyForCodeExchangePolicy.Required;
        application.name = "JavaExampleApp";
    
        // assign key from above to sign our tokens. This needs to be asymmetric
        application.jwtConfiguration = new JWTConfiguration();
        application.jwtConfiguration.enabled = true;
        application.jwtConfiguration.accessTokenKeyId = rsaKeyId;
        application.jwtConfiguration.idTokenKeyId = rsaKeyId;
    
        UUID clientId = UUID.fromString(APPLICATION_ID);
        String clientSecret = "change-this-in-production-to-be-a-real-secret";
    
        application.oauthConfiguration.clientSecret = clientSecret;
        ApplicationRequest applicationRequest = new ApplicationRequest(application);
        ClientResponse<ApplicationResponse, Errors> applicationResponse = client.createApplication(clientId, applicationRequest);
        if (!applicationResponse.wasSuccessful()) {
          throw new RuntimeException("couldn't create application");
        }
    
        // register user, there should be only one, so grab the first
        UserSearchCriteria userSearchCriteria = new UserSearchCriteria();
        userSearchCriteria.queryString = "*";
        SearchRequest searchRequest = new SearchRequest(userSearchCriteria );
    
        ClientResponse<SearchResponse, Errors> userSearchResponse = client.searchUsersByQuery(searchRequest);
        if (!userSearchResponse.wasSuccessful()) {
          throw new RuntimeException("couldn't find users");
        }
        User myUser = userSearchResponse.successResponse.users.get(0);
    
        // patch the user to make sure they have a full name, otherwise OIDC has issues
        Map<String, Object> fullNameUpdateMap = new HashMap<String, Object>();
        Map<String, Object> userMap = new HashMap<String, Object>();
        userMap.put("fullName",myUser.firstName+ " "+myUser.lastName);
        fullNameUpdateMap.put("user", userMap);
        ClientResponse<UserResponse, Errors> patchUserResponse = client.patchUser(myUser.id, fullNameUpdateMap);
        if (!patchUserResponse.wasSuccessful()) {
          throw new RuntimeException("couldn't update user");
        }
    
        // now register the user
        UserRegistration registration = new UserRegistration();
        registration.applicationId = clientId;
    
        // otherwise we try to create the user as well as add the registration
        User nullBecauseWeHaveExistingUser = null;
    
        RegistrationRequest registrationRequest = new RegistrationRequest(nullBecauseWeHaveExistingUser, registration );
        ClientResponse<RegistrationResponse, Errors> registrationResponse = client.register(myUser.id, registrationRequest);
        if (!registrationResponse.wasSuccessful()) {
          throw new RuntimeException("couldn't register user");
        }
      }
    }

    Then, you can run the setup class. This will create FusionAuth configuration for your Spring application.

    
    mvn compile && mvn exec:java \
      -Dexec.mainClass="io.fusionauth.example.Setup" \
      -Dfusionauth.api.key=<your API key>

    Create Your :technology: Application

    Now you are going to create a :technology: application. While this section uses a simple :technology: application, you can use the same configuration to integrate your :technology: application with FusionAuth.

    First, make a directory:

    
    mkdir ../setup-spring && cd ../setup-spring

    Then, install the following files in these locations.

    Put a pom.xml file at the top level. Here are the contents of this file:

    Your Spring pom.xml file
    
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    	<modelVersion>4.0.0</modelVersion>
    	<parent>
    		<groupId>org.springframework.boot</groupId>
    		<artifactId>spring-boot-starter-parent</artifactId>
    		<version>2.7.5</version>
    		<relativePath/> <!-- lookup parent from repository -->
    	</parent>
    	<groupId>io.fusionauth.example</groupId>
    	<artifactId>spring</artifactId>
    	<version>0.0.1-SNAPSHOT</version>
    	<name>spring</name>
    	<description>Demo project for Spring Boot</description>
    	<properties>
    		<java.version>17</java.version>
    	</properties>
    	<dependencies>
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-oauth2-client</artifactId>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-thymeleaf</artifactId>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-web</artifactId>
    		</dependency>
    
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-test</artifactId>
    			<scope>test</scope>
    		</dependency>
    	</dependencies>
    
    	<build>
    		<plugins>
    			<plugin>
    				<groupId>org.springframework.boot</groupId>
    				<artifactId>spring-boot-maven-plugin</artifactId>
    			</plugin>
    		</plugins>
    	</build>
    
    </project>

    Then, you need to create two directories:

    
    mkdir -p src/main/resources/templates && \
    mkdir -p src/main/java/io/fusionauth/example/spring/config

    Paste the below into src/main/resources/application.properties. This is mostly the OAuth configuration you need.

    
    
    spring.thymeleaf.cache=false
    spring.thymeleaf.enabled=true
    spring.thymeleaf.prefix=classpath:/templates/
    spring.thymeleaf.suffix=.html
    
    spring.application.name=FusionAuth Spring Example
    
    spring.security.oauth2.client.registration.fusionauth-client.client-id=e9fdb985-9173-4e01-9d73-ac2d60d1dc8e
    spring.security.oauth2.client.registration.fusionauth-client.client-secret=super-secret-secret-that-should-be-regenerated-for-production
    spring.security.oauth2.client.registration.fusionauth-client.scope=email,openid,profile
    spring.security.oauth2.client.registration.fusionauth-client.redirect-uri=http://localhost:8080/login/oauth2/code/fusionauth
    spring.security.oauth2.client.registration.fusionauth-client.client-name=fusionauth
    spring.security.oauth2.client.registration.fusionauth-client.provider=fusionauth
    spring.security.oauth2.client.registration.fusionauth-client.client-authentication-method=basic
    spring.security.oauth2.client.registration.fusionauth-client.authorization-grant-type=authorization_code
    
    spring.security.oauth2.client.provider.fusionauth.authorization-uri=http://localhost:9011/oauth2/authorize
    spring.security.oauth2.client.provider.fusionauth.token-uri=http://localhost:9011/oauth2/token
    spring.security.oauth2.client.provider.fusionauth.user-info-uri=http://localhost:9011/oauth2/userinfo?schema=openid
    spring.security.oauth2.client.provider.fusionauth.user-name-attribute=name
    spring.security.oauth2.client.provider.fusionauth.user-info-authentication-method=header
    spring.security.oauth2.client.provider.fusionauth.jwk-set-uri=http://localhost:9011/.well-known/jwks.json

    Then put this HTML in the src/main/resources/templates/home.html file. This is going to be the page unauthenticated users see.

    
    <html xmlns:th="http://www.w3.org/1999/xhtml" lang="en">
    <head><title>Home Page</title></head>
    <body>
    <h1>Hello !</h1>
    <p>Welcome to <span th:text="${appName}">Our App</span></p>
    
    <p>You can view your profile <a href="/user">here</a></p>
    </body>
    </html>

    Add this HTML in the src/main/resources/templates/user.html file. This is going to be the page authenticated users can access. This will only show a JSON representation of the user, but you could put other protected information in this page.

    
    <html xmlns:th="http://www.w3.org/1999/xhtml" lang="en">
    <head><title>User Profile</title></head>
    <body>
    <h1>Welcome to the protected User page. Below is your OpenID profile information.</h1>
    <p>Profile: <span th:text="${profile}"></span></p>
    
    <h2>You can logout here: <a href="http://localhost:9011/oauth2/logout?client_id=e9fdb985-9173-4e01-9d73-ac2d60d1dc8e">Logout</a></h2>
    </body>
    </html>

    Then, you need to add the Java files that comprise your Spring application. There are four:

    • An application startup class

    • A configuration class

    • Two controllers for the pages you added above

    Let’s add the startup file first. In src/main/java/io/fusionauth/example/spring/FusionAuthSpringApplication.java, put this code:

    
    package io.fusionauth.example.spring;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class FusionAuthSpringApplication {
    
    	public static void main(String[] args) {
    		SpringApplication.run(FusionAuthSpringApplication.class, args);
    	}
    
    }

    Next, the configuration class. In src/main/java/io/fusionauth/example/spring/config/SecurityConfiguration.java, put this code:

    
    package io.fusionauth.example.spring.config;
    
    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.oauth2.client.registration.ClientRegistrationRepository;
    import org.springframework.security.oauth2.client.web.DefaultOAuth2AuthorizationRequestResolver;
    import org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestCustomizers;
    import org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter;
    import org.springframework.security.web.SecurityFilterChain;
    
    @Configuration
    public class SecurityConfiguration {
    
        @Bean
        public SecurityFilterChain filterChain(HttpSecurity http, ClientRegistrationRepository repo)
                throws Exception {
    
            var base_uri = OAuth2AuthorizationRequestRedirectFilter.DEFAULT_AUTHORIZATION_REQUEST_BASE_URI;
            var resolver = new DefaultOAuth2AuthorizationRequestResolver(repo, base_uri);
    
            resolver.setAuthorizationRequestCustomizer(OAuth2AuthorizationRequestCustomizers.withPkce());
    
            http
                    .authorizeRequests(a -> a
                            .antMatchers("/").permitAll()
                            .anyRequest().authenticated())
                    .oauth2Login(login -> login.authorizationEndpoint().authorizationRequestResolver(resolver));
    
            http.logout(logout -> logout
                    .logoutSuccessUrl("/"));
    
            return http.build();
        }
    }

    Finally, create the home and user controllers which back the HTML templates above.

    Here’s the home controller, which should live in src/main/java/io/fusionauth/example/spring/HomeController.java, which should contain this code:

    
    package io.fusionauth.example.spring;
    
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    @Controller
    public class HomeController {
    
        @Value("${spring.application.name}")
        String appName;
    
        @RequestMapping("/")
        public String homePage(Model model) {
            model.addAttribute("appName", appName);
            return "home";
        }
    }

    Here’s the profile controller, which should live in src/main/java/io/fusionauth/example/spring/UserController.java. It should have this code:

    
    package io.fusionauth.example.spring;
    
    import org.springframework.security.core.annotation.AuthenticationPrincipal;
    import org.springframework.security.oauth2.core.oidc.user.OidcUser;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    @Controller
    public class UserController {
    
        public UserController() {
    
        }
    
        @RequestMapping("/user")
        public String userPage(Model model, @AuthenticationPrincipal OidcUser principal) {
            if (principal != null) {
                model.addAttribute("profile", principal.getClaims());
            }
            return "user";
        }
    }

    At the end, your directory tree should look like:

    
    ├── docker-compose.yml
    ├── setup-fusionauth
    │   ├── pom.xml
    │   └── src
    │       └── main
    │           └── java
    │               └── io
    │                   └── fusionauth
    │                       └── example
    │                           └── Setup.java
    └── setup-spring
        ├── pom.xml
        └── src
            └── main
                ├── java
                │   └── io
                │       └── fusionauth
                │           └── example
                │               └── spring
                │                   ├── FusionAuthSpringApplication.java
                │                   ├── HomeController.java
                │                   ├── UserController.java
                │                   └── config
                │                       └── SecurityConfiguration.java
                └── resources
                    ├── application.properties
                    └── templates
                        ├── home.html
                        └── user.html

    Once you’ve created this directory structure, you can start up the Spring application using this command:

    Start the application
    
    mvn spring-boot:run

    You can now open up an incognito window and visit the Spring app. Log in using the user you added in FusionAuth, and you’ll see a JSON output of your profile on the profile page.

    Feedback

    How helpful was this page?

    See a problem?

    File an issue in our docs repo

    Have a question or comment to share?

    Visit the FusionAuth community forum.

    © 2023 FusionAuth
    How-to
    Blog
    Expert Advice
    Download
    Subscribe for developer updates