๐ Implementing Secure Okta SSO in Spring Boot with Role-Based Access, JWT, Docker, and Terraform
"Securing Spring Boot with Okta SSO, JWT, and Role-Based Access โ From Setup to Deployment"
๐จโ๐ป I'm Praveen Gupta, a Senior Backend Engineer with over 10+ years of experience in designing scalable backend systems using Java, Spring Boot, Microservices, and AWS Cloud. I specialize in building cloud-native applications, integrating DevOps practices, and mentoring teams in writing clean, production-grade code. I created this blog to share real-world backend architecture tips, Spring Boot patterns, and practical coding solutions that help developers grow faster.
In this guide, youโll learn how to implement Single Sign-On (SSO) with Okta โ a secure and centralized authentication method where a single set of credentials grants access to multiple applications. Instead of forcing users to log in separately to each service, SSO authenticates them once through a trusted Identity Provider (IdP) like Okta and then issues tokens that allow seamless access to other connected systems. This improves user experience, reduces password fatigue, and strengthens security by enforcing centralized policies like MFA (Multi-Factor Authentication).
Weโll protect your Spring Boot APIs with JWT-based authorization, so every request is verified against a digitally signed token issued by Okta. This ensures that not only is the user authenticated, but also authorized to perform specific actions based on their roles or scopes.
For deployment, weโll use Docker to package the application for portability, Terraform to provision and manage infrastructure on AWS, and GitHub Actions to automate CI/CD pipelines.
The implementation will be production-grade โ using Java 21 for the latest performance and language features, .properties configuration for clarity and maintainability, and role-based security to precisely control access to APIs.
With this approach, youโll end up with a secure, scalable, and cloud-ready SSO-enabled Spring Boot application that can be reused across projects and easily integrated into enterprise ecosystems.
๐ Goal of This Project
We aim to secure a Spring Boot application using:
โ Okta SSO (OAuth2 + OIDC)
๐ JWT access tokens
๐ฅ Role-based authorization
๐ Token expiration & re-signing
๐ณ Docker for packaging
โ๏ธ Terraform for AWS hosting
๐ GitHub Actions for CI/CD
This architecture supports SSO login, fine-grained access control, and token lifecycle management.

โ Step 1: Register Application in Okta
Sign up at https://developer.okta.com
Create a new application:
Go to Applications > Create App Integration
Choose OIDC - Web Application
Set redirect URI to:
http://localhost:8080/login/oauth2/code/okta
Save the Client ID and Client Secret
Under Security > API > Authorization Servers, configure custom claims:
Add
"groups"or"roles"to the token payloadThis enables Spring to apply role-based access control
โ๏ธ Step 2: Spring Boot Configuration
Use application.properties for a cleaner and environment-friendly setup.
spring.security.oauth2.client.registration.okta.client-id=...
spring.security.oauth2.client.registration.okta.client-secret=...
spring.security.oauth2.client.registration.okta.scope=openid,profile,email
spring.security.oauth2.client.provider.okta.issuer-uri=https://dev-xxxx.okta.com/oauth2/default
spring.security.oauth2.resourceserver.jwt.issuer-uri=https://dev-xxxx.okta.com/oauth2/default
spring.security.oauth2.resourceserver.jwt.jwk-set-uri=https://dev-xxxx.okta.com/oauth2/default/v1/keys
token.validity.seconds=3600
๐ Step 3: Role-Based Controller Setup
Using Spring annotations like @PreAuthorize, you can easily enforce access rules.
@GetMapping("/user")
@PreAuthorize("hasAuthority('SCOPE_profile')")
public Map<String, Object> getUser(@AuthenticationPrincipal OidcUser user) {
return user.getClaims();
}
@GetMapping("/admin")
@PreAuthorize("hasRole('ADMIN')")
public String adminPanel() {
return "Welcome, Admin!";
}
๐ User endpoint is accessible to anyone with the
profilescope๐ Admin endpoint is accessible only to users with the
ADMINrole
๐ก Step 4: SecurityConfig + Token Validation
Hereโs how we configure Spring Security to use Okta JWT tokens and enforce method security:
@EnableMethodSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/", "/error").permitAll()
.anyRequest().authenticated()
)
.oauth2Login().and()
.oauth2ResourceServer().jwt();
return http.build();
}
}
๐ JWT Expiration Check (Optional)
public boolean isTokenExpired(String jwt) {
SignedJWT signedJWT = SignedJWT.parse(jwt);
Date expiry = signedJWT.getJWTClaimsSet().getExpirationTime();
return expiry.before(Date.from(Instant.now()));
}
โ Built-in expiration is automatically enforced by Spring. This utility is useful for debugging or custom token inspection.
๐ Step 5: Token Re-signing / Refresh Flow
What Happens When the Token Expires?
When the
access_tokenexpires, the app uses therefresh_tokento get a new token from Okta.Use the
/tokenendpoint:POST /oauth2/default/v1/token grant_type=refresh_token refresh_token=...
Want to Handle This In-House?
You can run your own Spring Authorization Server to issue, re-sign, and rotate JWT tokens internally using asymmetric keys.
๐ณ Step 6: Dockerfile for Deployment
FROM eclipse-temurin:21-jdk-alpine
COPY target/*.jar app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
โ Small image
โ Java 21 support
โ Runs anywhere (local, cloud, CI/CD)
โ๏ธ Step 7: Terraform + AWS EC2
Provision AWS infra with Terraform to host your app.
resource "aws_instance" "spring_app" {
ami = "ami-0c02fb55956c7d316"
instance_type = "t3.micro"
...
}
Installs Docker
Pulls app image from Docker Hub
Runs container on port 443 with HTTPS
Configures the security group to allow HTTPS traffic
๐ Step 8: GitHub Actions for CI/CD
- name: Build & Push Docker image
run: |
docker build -t your-dockerhub/okta-sso-app .
docker push your-dockerhub/okta-sso-app
Add DOCKER_USERNAME and DOCKER_PASSWORD to GitHub Secrets.
โ
Push to main branch โ App automatically builds and deploys!
๐งช Testing the Workflow
Navigate to
/โ You'll be redirected to Okta loginLog in โ You'll be redirected back with the JWT token
Visit
/userโ See your token claimsVisit
/adminโ Only works if you have theADMINrole
๐ก๏ธ Security Best Practices
โ Always use HTTPS (e.g., via NGINX or Load Balancer)
โ Set short expiration times on tokens (e.g., 1 hour)
โ Rotate signing keys frequently (use JWKs)
โ Store
refresh_tokensecurelyโ Validate audience (
aud) and issuer (iss) in JWT
๐ GitHub Repository
๐ https://github.com/praveennic17/okta-sso-spring-boot-v1
You can deploy it using:
Docker locally
AWS EC2 via Terraform
GitHub Actions CI/CD
Okta developer account for free auth
๐ Whatโs Next?
In the next article, weโll dive deeper into how JWT works โ breaking down its structure (Header, Payload, Signature), how itโs generated, signed, and validated, and common pitfalls to avoid when using JWT in real-world applications.
๐ฌ Feedback?
Found this useful?
Leave a comment or connect with me on LinkedIn.
