Learning Java - Modern Security Patterns & Access Control
Series/Learn Java/Episode 14
Episode 14 of 24

Learning Java - Modern Security Patterns & Access Control

This episode covers modern security patterns in Java: an introduction to OAuth 2.0 and OpenID Connect, integration with Spring Security and Jakarta Security, secure headers, CORS, CSRF, mitigation of common attacks, and managing credentials and secrets in production environments.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Introduction

Episode 13 built the cryptography foundation; episode 14 takes you to the modern security patterns and access control used by enterprise applications. You will learn OAuth 2.0 and OpenID Connect, integrate Spring Security, understand secure headers, CORS, and CSRF, and manage secrets in production.

Modern application security is not just encryption — it is about managing identity, controlling access rights, and protecting applications from ever-evolving attacks. This episode gives you the complete map.

Introduction to OAuth 2.0 and OpenID Connect

OAuth 2.0 for Authorization

OAuth 2.0 is the authorization standard that lets an application access resources on behalf of a user without sharing credentials. The basic flow: the client requests a token from the authorization server, then uses that token to access the resource server.

OpenID Connect for Authentication

OpenID Connect (OIDC) is built on top of OAuth 2.0 and adds an authentication layer. It introduces the ID token that carries the user's identity. In the Java ecosystem, popular OIDC providers such as Keycloak and Okta are often used.

OAuth 2.0 + OIDC flow
klien -> minta otorisasi -> server otorisasi -> access + ID token -> akses resource

Integration with Spring Security / Jakarta Security

Adding Spring Security

Spring Security is the de facto security standard for Spring Boot. Add the dependency:

Add Spring Security
mvn dependency:get -Dartifact=org.springframework.boot:spring-boot-starter-security:3.3.2

Resource Server with JWT

A simple configuration for validating JWTs from the authorization server:

Resource server with JWT
import org.springframework.context.annotation.*;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
 
@Configuration
public class SecurityConfig {
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/public/**").permitAll()
                .anyRequest().authenticated())
            .oauth2ResourceServer(rs -> rs.jwt());
        return http.build();
    }
}

oauth2ResourceServer(rs -> rs.jwt()) makes the application validate JWTs on every protected request.

Jakarta Security

For Jakarta EE environments, use Jakarta Security with annotations:

Jakarta Security with annotations
import jakarta.annotation.security.RolesAllowed;
 
@RolesAllowed({"ADMIN", "USER"})
public class LayananData {
    public String ambilData() {
        return "data sensitif";
    }
}

@RolesAllowed({...}) restricts method access based on the user's role.

Secure Headers, CORS, CSRF, and Attack Mitigation

Secure Headers

Security headers protect applications from browser-based attacks. Spring Security adds many headers by default: X-Content-Type-Options, X-Frame-Options, and Strict-Transport-Security. They can also be added manually:

Adding secure headers
http.headers(headers -> headers
    .contentSecurityPolicy(csp -> csp.policyDirectives(
        "default-src 'self'; frame-ancestors 'none'")));

CORS: Origin Control

CORS (Cross-Origin Resource Sharing) determines which origins are allowed to access the API. Configure the origin whitelist:

CORS configuration
http.cors(cors -> cors.configurationSource(request -> {
    var config = new org.springframework.web.cors.CorsConfiguration();
    config.setAllowedOrigins(java.util.List.of("https://app.example.com"));
    config.setAllowedMethods(java.util.List.of("GET", "POST", "PUT", "DELETE"));
    return config;
}));

CSRF and Mitigation of Common Attacks

CSRF (Cross-Site Request Forgery) is prevented with a CSRF token — enabled by default for session-based applications. For stateless APIs, CSRF is often disabled because there is no session. Other common attacks that must be mitigated: SQL injection with prepared statements, XSS with output escaping, and brute force with rate limiting.

Managing Credentials and Secrets in Production

Do Not Hardcode Credentials

Credentials such as the OAuth client secret and database passwords must not be in source code. Use environment variables as discussed in episode 11:

Supply secrets via the environment
export CLIENT_ID="aplikasi-web"
export CLIENT_SECRET="rahasia-sangat-sensitif"

Secret Manager in Production

In production environments, use a secret manager: HashiCorp Vault, AWS Secrets Manager, or the secret features of your cloud platform. The application reads secrets at runtime, so the code stays clean and secrets can be rotated without redeploying.

Info

Make sure secrets are rotated periodically, use the principle of least privilege, and give secret manager access only to the services that truly need it.

Closing

Episode 14 covers modern security patterns: OAuth 2.0 and OpenID Connect for authorization and authentication, Spring Security and Jakarta Security for application protection, secure headers, CORS, CSRF, mitigation of common attacks, and managing credentials and secrets in production.

Key takeaways:

  • OAuth 2.0 handles authorization; OIDC adds authentication.
  • Spring Security validates JWTs through the resource server.
  • Jakarta Security uses annotations such as @RolesAllowed.
  • Secure headers, CORS, and CSRF protect web applications.
  • Mitigation of SQL injection, XSS, and brute force is mandatory.
  • Production secrets are managed via a secret manager and rotated periodically.

In the next episode, episode 15, we will discuss concurrency and parallelism — basic threads, runnable, and thread lifecycle, ExecutorService, thread pools, and task scheduling, synchronization, locks, atomic variables, and concurrent collections, plus the Java Flow API, reactive streams, and the java.util.concurrent structure. Time to leverage the multi-core!

Learning Java - Modern Security Patterns & Access Control | Learn Java