Hello World Full-Stack Security: React/JavaScript + Spring/Java
Updated on September 8, 2023Developers can easily secure a full-stack application using Auth0 by Okta. This code sample demonstrates how to implement authentication in a client application built with React and JavaScript, as well as how to implement authorization in an API server built with Spring and Java. You'll connect the client and server applications to see the full security flow in action!
Let's get started!
Quick Auth0 Set Up
To get started, create an Auth0 account to connect your application with the Auth0 Identity Platform. You can also use any of your existing Auth0 accounts.
Get the Auth0 domain and client ID
-
Open the Applications section of the Auth0 Dashboard.
-
Click on the Create Application button and fill out the form with the following values:
-
Name:
Hello World Client
-
Application Type: Single Page Web Applications
-
-
Click on the Create button.
An Auth0 Application page loads up.
As such, click on the "Settings" tab of your Auth0 Application page, locate the "Application URIs " section, and fill in the following values:
-
Allowed Callback URLs:
http://localhost:4040/callback
-
Allowed Logout URLs:
http://localhost:4040
-
Allowed Web Origins:
http://localhost:4040
Scroll down and click the "Save Changes" button.
Next, locate the "Basic Information" section.
When you enter a value in the input fields present on this page, any code snippet that uses such value updates to reflect it. Using the input fields makes it easy to copy and paste code as you follow along.
As such, enter the "Domain" and "Client ID" values in the following fields to set up your single-page application in the next section:
Get the Auth0 audience
-
Open the APIs section of the Auth0 Dashboard.
-
Click on the Create API button and fill out the "New API" form with the following values:
-
Name:
Hello World Server
-
Identifier:
https://hello-world.example.com
-
-
Click on the Create button.
When setting up APIs, we also refer to the API identifier as the Audience value. Store that value in the following field to set up your API server in the next section:
Set Up and Run the Spring Project
Start by cloning the Spring project:
git clone https://github.com/auth0-developer-hub/api_spring_java_hello-world.git
Make the project directory your current working directory:
cd api_spring_java_hello-world
Then, check out the basic-role-based-access-control
branch, which holds all the code related to implementing token-based authorization to protect resources in a Spring API:
git checkout basic-role-based-access-control
Install the Spring project dependencies using Gradle:
./gradlew dependencies --write-locks
Now, create a .env
file under the project directory and populate it as follows:
PORT=6060CLIENT_ORIGIN_URL=http://localhost:4040OKTA_OAUTH2_ISSUER=https://AUTH0-DOMAIN/OKTA_OAUTH2_AUDIENCE=AUTH0-AUDIENCE
Execute the following command to run the Spring API server:
./gradlew bootRun
Optional: Enable hot swapping
Spring Boot supports hot swapping. The spring-boot-devtools
module includes support for restarting your application automatically as your project code changes.
You have two options to use Spring Boot hot swapping:
Use Spring Tools
You can install Spring Tools in your project. Then, whenever you run the Spring server from your IDE, hot swapping will be enabled.
Spring Tools will handle watching project files, recompiling, and restarting the server as you make code changes in your project.
Using the Gradle Wrapper
You can run the Gradle Wrapper in a terminal application as follows:
- Open a terminal window to watch and compile the Spring Boot project:
./gradlew compileJava -t
- Open a second terminal window to start the server:
./gradlew bootRun
Running those Gradle tasks in parallel enables Spring Boot hot swapping. The server will automatically restart when you make code changes in your project.
Set Up and Run the React Project
Start by cloning the project into your local machine:
git clone https://github.com/auth0-developer-hub/spa_react_javascript_hello-world.git
Make the project directory your current working directory:
cd spa_react_javascript_hello-world
Then, check out the basic-authentication-with-api-integration
branch, which holds all the React code related to implementing user login with Auth0 and requesting protected resources from an API:
git checkout basic-authentication-with-api-integration
Next, install the React project dependencies:
npm install
Once you have access to the React project, create a .env
file under the project directory and populate it as follows:
REACT_APP_AUTH0_DOMAIN=AUTH0-DOMAINREACT_APP_AUTH0_CLIENT_ID=AUTH0-CLIENT-IDREACT_APP_AUTH0_CALLBACK_URL=http://localhost:4040/callbackREACT_APP_API_SERVER_URL=http://localhost:6060REACT_APP_AUTH0_AUDIENCE=AUTH0-AUDIENCE
Run the React application by issuing the following command:
npm start
You can now visit http://localhost:4040/
to access the application.
There's something missing in this React code sample. There's no login or sign-up forms!
When you use Auth0, you don't need to build any login or sign-up forms! Your users can log in to your application through a page hosted by Auth0, which provides a secure, standards-based login experience. You can customize the Auth0 login page with your branding and enable different authentication methods, such as logging in with a username/password combination or a social provider like Facebook or Google.
Once you log in, visit the protected "Profile" page (http://localhost:4040/profile
) to see all the user profile information that Auth0 securely shares with your application using ID tokens.
Then, visit the "Protected" page (http://localhost:4040/protected
) or the "Admin" page (http://localhost:4040/admin
) to practice requesting protected resources from an external API server using access tokens.
Set Up Role-Based Access Control (RBAC)
The access token present in the authorization header of a request must include a permissions
claim that contains the read:admin-messages
permission to access the GET /api/messages/admin
endpoint.
You can use the Auth0 Dashboard to enable Role-Based Access Control (RBAC) and then implement it by creating API permissions, assigning those permissions to a role, and assigning that role to a user.
Enable Role-Based Access Control (RBAC)
-
Open the APIs section of the Auth0 Dashboard and select your "Hello World Server" registration.
-
Click on the "Settings" tab and locate the "RBAC Settings" section.
-
Switch on the "Enable RBAC" and "Add Permissions in the Access Token" options.
Create an API permission
In the same Auth0 API registration page, follow these steps:
-
Click on the "Permissions" tab and fill a field from the "Add a Permission (Scope)" section with the following information:
- Permission (Scope):
read:admin-messages
- Description:
Read admin messages
- Permission (Scope):
-
Click the "+ Add" button to store the permission.
Create a role with permissions
Create a role
-
Open the Roles section of the Auth0 Dashboard.
-
Click on the Create role button and fill out the "New Role" form with the following values:
-
Name:
messages-admin
-
Description:
Read admin messages
.
-
-
Click on the Create button.
Add permissions to the role
-
Click on the "Permissions" tab of the roles page.
-
Click on the "Add Permissions" button.
-
Select the "Hello World Server" from the dropdown menu that comes up and click the "Add Permissions" button.
-
Select all the permissions available by clicking on them one by one or by using the "All" link.
-
Finally, click on the "Add Permissions" button to finish up.
Create an admin user
-
Open the Users section from the Auth0 Dashboard.
-
Click on the "Create user" button and fill out the form with the required information. Alternatively, you can also click on any of your existing users to give one of them the admin role.
-
On the user's page, click on the "Roles" tab and then click on the "Assign Roles" button.
-
Select the
messages-admin
role from the dropdown menu and click on the "Assign" button.
Access the admin endpoint
Head to the client application, log in and visit the guarded http://localhost:4040/admin
page.
When you log in to a "Hello World" client application as a user who has the messages-admin
role, your access token will have the required permissions to access the GET /api/messages/admin
endpoint, and you'll get the following response:
{"text": "This is an admin message."}
However, when you log in as a user who doesn't have the messages-admin
role, you'll get a 403 Forbidden
status code and the following response:
{"message": "Permission denied"}