In this tutorial, we will create a Spring Boot application and secure it using JWT (JSON Web Tokens) with JWS (JSON Web Signature) and JWK (JSON Web Key) in Spring Security OAuth2.
Prerequisites
- Basic understanding of Spring Boot and Spring Security
- JDK installed on your machine
- Maven or Gradle installed
Step 1: Setup a Spring Boot Project
First, let’s create a new Spring Boot project. You can do this manually or use the Spring Initializr to generate a project with the required dependencies.
For Maven, add the following dependencies:
- Spring Web
- Spring Security
- Spring Security OAuth2 JWT
Here’s an example pom.xml
for Maven:
<dependencies>
<!-- Spring Boot Starter Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- Spring Security OAuth2 JWT -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-jose</artifactId>
</dependency>
</dependencies>
Step 2: Configure Spring Security
Create a new class SecurityConfig
to configure Spring 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.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.security.oauth2.jwt.NimbusJwtDecoderJwkSupport;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests(authorize -> authorize
.anyRequest().authenticated()
)
.oauth2ResourceServer(oauth2 -> oauth2
.jwt(jwt -> jwt.decoder(jwtDecoder()))
);
}
@Bean
public JwtDecoder jwtDecoder() {
return NimbusJwtDecoderJwkSupport.withJwkSetUri("https://example.com/.well-known/jwks.json").build();
}
}
In this configuration:
configure(HttpSecurity http)
method configures the security rules.oauth2ResourceServer(jwt -> jwt.decoder(jwtDecoder()))
configures the OAuth2 resource server to use a JWT decoder.jwtDecoder()
method creates aJwtDecoder
bean using JWK set URI.
Step 3: Create a Controller
Let’s create a simple REST controller for testing our secure endpoint:
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello() {
return "Hello, secured user!";
}
}
Step 4: Generate JWK
You can generate a sample JWK for testing purposes using online tools or libraries. Here’s an example:
{
"keys": [
{
"kty": "RSA",
"e": "AQAB",
"n": "v6uCJ26eJk5Dbg6fK_KTVZjR9Tzx0sy7MyEi8gSTzIJ0r5GN..."
}
]
}
Step 5: Test the Application
Now you can run your Spring Boot application and test the /hello
endpoint. You will need a valid JWT to access this endpoint. You can obtain a JWT from an authentication server or generate one using online tools.
Here’s an example of how you can use curl
to test the endpoint:
curl -X GET http://localhost:8080/hello \
-H "Authorization: Bearer <your_jwt_token>"
Replace <your_jwt_token>
with your actual JWT token.
Summary
In this tutorial, we’ve set up a basic Spring Boot application secured with JWT + JWS + JWK using Spring Security OAuth2. We configured Spring Security to use a JWT decoder with a JWK set URI and created a simple REST endpoint to test the security. This is just a starting point, and in a real-world application, you would integrate with an authentication server to obtain valid JWT tokens for users.