Chaturmind
LearnDSASystem DesignInterview PrepDevOpsEngineering GrowthBlog
Start learning
Chaturmind

Structured learning paths for engineers who want to go deep. Written by practitioners.

Learn

  • Java
  • DSA
  • System Design
  • Spring Boot
  • AI / ML
  • DevOps
  • Engineering Growth
  • Java Interview Prep

Company

  • Blog
  • Contact

Legal

  • Privacy Policy
  • Terms of Service

© 2026 Chaturmind. All rights reserved.

Built for engineers who want to go deep.


← Java Interview Prep: 5–8 Years

Revise the 2–5 Years Tier

  • Revise: Core Java & Java 8+ (2–5 Years Tier)
  • Revise: Multithreading & Concurrency (2–5 Years Tier)
  • Revise: Spring Framework, Spring Boot & Security (2–5 Years Tier)
  • Revise: Kafka, Git/Maven/Gradle, Deployment & Testing (2–5 Years Tier)

Advanced Core Java

  • Advanced OOP & Design Scenarios — Interview Questions
  • Advanced Concurrency, Collections & Memory — Interview Questions
  • Modern Java Language Features & Annotations — Interview Questions
  • Class Loading, Reflection, Serialization & Idioms — Interview Questions

Java Design Patterns in Depth

  • Design Patterns Overview & Singleton — Interview Questions
  • Factory & Abstract Factory Patterns — Interview Questions
  • Builder & Prototype Patterns — Interview Questions
  • Adapter & Bridge Patterns — Interview Questions
  • Composite & Decorator Patterns — Interview Questions
  • Facade & Proxy Patterns — Interview Questions
  • Chain of Responsibility & Observer Patterns — Interview Questions
  • Strategy & Template Method Patterns — Interview Questions
  • Command Pattern — Interview Questions

Advanced Spring Boot

  • Logging, Configuration & Actuator (Advanced) — Interview Questions
  • Transactions, Multiple Datasources & Query Tuning — Interview Questions
  • Validation & REST API Design (Advanced) — Interview Questions
  • Reactive, Async & Scheduling in Spring Boot — Interview Questions
  • Deployment, High Availability, Scaling & Caching — Interview Questions
  • Custom Starters, DI, Testing & DevTools — Interview Questions

Spring Security for APIs

  • Securing REST APIs End to End — Interview Questions

Microservices at Scale

  • Monolith Migration, Communication & Spring Cloud — Interview Questions
  • Data Consistency, Sagas & Kafka Messaging — Interview Questions
  • Tracing, Discovery, Load Balancing, Service Mesh & Resilience — Interview Questions
  • Deployment, Scaling & Security for Microservices — Interview Questions

Microservice Design Patterns

  • API Gateway, Circuit Breaker & Retry Patterns — Interview Questions
  • Service Discovery & Database per Service Patterns — Interview Questions
  • Saga, Choreography & Orchestration Patterns — Interview Questions
  • Bulkhead & Strangler Fig Patterns — Interview Questions
Chaturmind
← Java Interview Prep: 5–8 Years

Revise the 2–5 Years Tier

  • Revise: Core Java & Java 8+ (2–5 Years Tier)
  • Revise: Multithreading & Concurrency (2–5 Years Tier)
  • Revise: Spring Framework, Spring Boot & Security (2–5 Years Tier)
  • Revise: Kafka, Git/Maven/Gradle, Deployment & Testing (2–5 Years Tier)

Advanced Core Java

  • Advanced OOP & Design Scenarios — Interview Questions
  • Advanced Concurrency, Collections & Memory — Interview Questions
  • Modern Java Language Features & Annotations — Interview Questions
  • Class Loading, Reflection, Serialization & Idioms — Interview Questions

Java Design Patterns in Depth

  • Design Patterns Overview & Singleton — Interview Questions
  • Factory & Abstract Factory Patterns — Interview Questions
  • Builder & Prototype Patterns — Interview Questions
  • Adapter & Bridge Patterns — Interview Questions
  • Composite & Decorator Patterns — Interview Questions
  • Facade & Proxy Patterns — Interview Questions
  • Chain of Responsibility & Observer Patterns — Interview Questions
  • Strategy & Template Method Patterns — Interview Questions
  • Command Pattern — Interview Questions

Advanced Spring Boot

  • Logging, Configuration & Actuator (Advanced) — Interview Questions
  • Transactions, Multiple Datasources & Query Tuning — Interview Questions
  • Validation & REST API Design (Advanced) — Interview Questions
  • Reactive, Async & Scheduling in Spring Boot — Interview Questions
  • Deployment, High Availability, Scaling & Caching — Interview Questions
  • Custom Starters, DI, Testing & DevTools — Interview Questions

Spring Security for APIs

  • Securing REST APIs End to End — Interview Questions

Microservices at Scale

  • Monolith Migration, Communication & Spring Cloud — Interview Questions
  • Data Consistency, Sagas & Kafka Messaging — Interview Questions
  • Tracing, Discovery, Load Balancing, Service Mesh & Resilience — Interview Questions
  • Deployment, Scaling & Security for Microservices — Interview Questions

Microservice Design Patterns

  • API Gateway, Circuit Breaker & Retry Patterns — Interview Questions
  • Service Discovery & Database per Service Patterns — Interview Questions
  • Saga, Choreography & Orchestration Patterns — Interview Questions
  • Bulkhead & Strangler Fig Patterns — Interview Questions
HomeLearnJava Interview PrepJava Interview Prep: 5–8 YearsSpring Security for APIs
✓ FreeAdvanced· 12 min read

Securing REST APIs End to End — Interview Questions

Securing a REST API step by step (TLS, authentication, authorisation, validation, rate limiting, secrets, headers, logging), Spring Security options (Basic, JWT resource server, OAuth2/OIDC, mTLS), JWT structure and pitfalls, a banking-grade security design, authentication and authorisation in Spring Boot, service-to-service security, URL vs method security, the modern core classes (SecurityFilterChain, not WebSecurityConfigurerAdapter), and the complete stateless JWT flow.

Published September 25, 2026


How to use this lesson

"How would you secure a REST API?" is a breadth question. Answer it in layers:

  1. Transport.
  2. Identity.
  3. Permissions.
  4. Input.
  5. Abuse.
  6. Secrets.
  7. Monitoring.

Then go deep on the Spring Security specifics, using Spring Security 6 APIs: SecurityFilterChain beans and authorizeHttpRequests. WebSecurityConfigurerAdapter was removed, and naming it as a core class is a red flag.

Q1. How would you secure a REST API? Give all the methods, step by step.

Short answer:

  1. Transport:
    • HTTPS/TLS 1.2+ everywhere, with HSTS.
    • No sensitive data in URLs (they get logged).
  2. Authentication:
    • OAuth2/OIDC: users log in at an identity provider, and the API validates access tokens (JWTs) as a resource server.
    • API keys or client credentials for machine clients.
    • mTLS for high-trust partners.
  3. Authorisation:
    • Deny by default.
    • Coarse URL rules, plus fine method-level checks (@PreAuthorize).
    • Object-level checks: "does this account belong to this user?" (prevents IDOR/BOLA, the #1 OWASP API risk).
    • Scopes and roles from the token.
  4. Input and output:
    • Validate every input (Bean Validation), limit sizes.
    • Parameterised queries (JPA or prepared statements) against injection.
    • Output DTOs that never leak internal fields.
    • Consistent error messages that don't reveal stack traces.
  5. Abuse protection:
    • Rate limiting and quotas (gateway, Bucket4j or Redis).
    • Payload limits.
    • Brute-force lockout on login.
    • Bot protection for public endpoints.
  6. Browser concerns:
    • A CORS allow-list.
    • CSRF protection if you use cookies.
    • Security headers: CSP, X-Content-Type-Options, frame options.
  7. Secrets and data:
    • A secrets manager; key rotation.
    • Hashed passwords (BCrypt or Argon2).
    • Encryption at rest for sensitive fields.
  8. Operations:
    • Audit logging of security events (without tokens or personal data).
    • Monitoring and alerting on anomalies.
    • Dependency scanning.
    • Penetration testing against the OWASP API Top 10.

Learn it in depth → Spring Security Overview

Q2. What options are there for securing a REST API in Spring Boot?

Short answer: Spring Security (spring-boot-starter-security) supports:

  • HTTP Basic: simple, for internal tools or behind a gateway, and only over TLS.
  • Session or form login: for server-rendered applications.
  • OAuth2 resource server with JWTs (spring-boot-starter-oauth2-resource-server): the standard for APIs. It validates the signature, issuer, audience and expiry against the identity provider's JWKS. Opaque tokens are validated by introspection.
  • OAuth2 client and OIDC login (-oauth2-client): for applications that log users in through Keycloak, Okta, Auth0, Entra ID or Google.
  • Custom API-key filters.
  • mTLS (X.509) authentication.
  • SAML 2.0 for enterprise SSO.
  • Method security (@EnableMethodSecurity, @PreAuthorize).
  • CORS and CSRF configuration, and security headers.
  • Password encoding (DelegatingPasswordEncoder).

Q3. What's inside a JWT?

Short answer: A JWT is three Base64URL parts separated by dots: header.payload.signature.

  • Header: alg (for example RS256 or ES256), typ, and kid, the key ID used for rotation.
  • Payload (claims):
    • Registered claims: iss (issuer), sub (subject, the user ID), aud (audience), exp (expiry), iat (issued at), nbf, jti (a unique ID).
    • Custom or private claims: roles, scopes (scope/scp), tenant.
  • Signature: computed over the header and payload with the issuer's key. HMAC uses a shared secret; RSA or EC use a private key, verified with the public key.

Key points to cover:

  • Signed ≠ encrypted. Anyone can Base64-decode the payload, so never put secrets or sensitive personal data in it. Use JWE if you need encryption.
  • Validation must check:
    • the signature, with an allow-listed algorithm (reject alg: none and algorithm-confusion tricks);
    • exp/nbf with a small clock skew;
    • iss and aud.
  • JWTs can't be revoked before they expire. Use short-lived access tokens (5–15 minutes) plus rotating refresh tokens, and a denylist (jti) if you need immediate revocation.

Learn it in depth → JWT Authentication

Q4. How do you implement authentication and authorisation in Spring Boot?

Short answer: Add spring-boot-starter-security. Then define:

  • authentication: where identities come from (a UserDetailsService backed by a database, LDAP, or an OAuth2/OIDC provider);
  • authorisation: which requests or methods need which authorities.

Do both as beans:

@Configuration
@EnableMethodSecurity
class SecurityConfig {
    @Bean
    SecurityFilterChain api(HttpSecurity http) throws Exception {
        return http
            .csrf(csrf -> csrf.disable())                                      // stateless bearer-token API (no cookies)
            .sessionManagement(s -> s.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/actuator/health/**", "/public/**").permitAll()
                .requestMatchers(HttpMethod.GET, "/api/products/**").hasAuthority("SCOPE_catalog.read")
                .requestMatchers("/api/admin/**").hasRole("ADMIN")
                .anyRequest().authenticated())                                 // deny-by-default posture
            .oauth2ResourceServer(o -> o.jwt(jwt -> jwt.jwtAuthenticationConverter(rolesFromClaim())))
            .build();
    }

    @Bean PasswordEncoder passwordEncoder() { return PasswordEncoderFactories.createDelegatingPasswordEncoder(); }   // for local users
}
spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: https://auth.shopin.example/realms/shop     # discovers the JWKS; validates iss and exp
          audiences: orders-api

Key points to cover:

  • Authentication answers "who are you?". It results in an Authentication stored in the SecurityContext.
  • Authorisation answers "what may you do?". AuthorizationManagers check URL rules, and @PreAuthorize checks methods.
  • An unauthenticated request gets a 401 (from the AuthenticationEntryPoint). An authenticated request without permission gets a 403 (from the AccessDeniedHandler).

Learn it in depth → Authentication Mechanics

Q5. How do you implement authentication and authorisation in Spring Boot? (The Spring Boot course variant)

Short answer: The same foundation as Q4, stated as the steps an interviewer expects:

  1. Add the security starter. Everything is now secured, with a generated default user, which is for development only.
  2. Provide a UserDetailsService (a JPA-backed user table), plus a PasswordEncoder (BCrypt or Argon2). Or delegate to an identity provider with OAuth2/OIDC.
  3. Declare a SecurityFilterChain, with URL rules by role or authority.
  4. Enable method security, for business-rule checks like ownership.
  5. Handle 401 and 403 with consistent JSON bodies.
  6. Test with @WithMockUser, jwt() post-processors and spring-security-test.
@PreAuthorize("hasRole('CUSTOMER') and @orderAccess.isOwner(#orderId, authentication)")
public OrderDto getOrder(UUID orderId) { ... }

Learn it in depth → Role-Based Access Control

Q6. You're designing a secure REST API for a banking application. Which security practices would you implement?

Short answer: Everything from Q1, raised to regulated-industry level:

  • Identity:
    • OAuth2/OIDC with MFA and step-up authentication for sensitive actions (adding a payee, large transfers).
    • Short-lived tokens, sender-constrained tokens (DPoP or mTLS-bound), and refresh-token rotation.
    • FAPI profiles for open banking.
  • Authorisation:
    • Strict object-level checks (account ownership) on every call.
    • Least-privilege scopes, and maker-checker (four-eyes) approval for admin operations.
  • Transactions:
    • Idempotency keys on transfer POSTs.
    • Replay protection (timestamps and nonces, or signed requests).
    • Transaction limits and velocity checks.
    • Fraud and risk scoring.
  • Data:
    • Encryption in transit (TLS 1.2+, mTLS between services) and at rest, with HSM/KMS-managed keys.
    • Field-level encryption or tokenisation for card numbers (PCI DSS).
    • Masking in logs and responses.
  • Input and abuse:
    • Strict validation (Bean Validation), parameterised queries, and output encoding.
    • Rate limiting and account-lockout policies.
    • A WAF at the edge.
  • CSRF: needed if the web banking UI uses cookie sessions. Not needed for pure bearer-token APIs (don't enable it blindly; understand why).
  • Audit and monitoring:
    • Tamper-evident audit logs of who did what, and when.
    • Monitoring and SIEM alerts on anomalies.
    • Retention per regulation.
  • Process:
    • Threat modelling, SAST/DAST, dependency and container scanning, penetration tests, and secrets in a vault.
    • Compliance (PCI DSS, RBI/PSD2 and local regulators).

Q7. How do you secure service-to-service communication?

Short answer:

  • Identity for services: use the OAuth2 client-credentials grant. Each service gets its own client, and requests tokens with an audience and scopes for the target service. The target validates them as a resource server.
  • Or propagate the user's context, through token exchange (RFC 8693), so downstream services still know the end user.
  • Transport: mTLS, usually provided by a service mesh (Istio or Linkerd) with automatic certificate rotation (SPIFFE/SPIRE identities). That encrypts traffic and authenticates workloads.
  • Zero trust: don't trust the network, even "inside" the cluster. Enforce authorisation policies per service (the mesh's AuthorizationPolicy, and Kubernetes NetworkPolicies).
  • The API gateway secures the north-south edge (external clients). East-west (service-to-service) calls still need their own authentication.
  • Secrets: no shared static passwords. Use workload identity (Kubernetes service accounts mapped to cloud IAM), and short-lived credentials.
@Bean
RestClient inventoryClient(RestClient.Builder builder, OAuth2AuthorizedClientManager clients) {
    var interceptor = new OAuth2ClientHttpRequestInterceptor(clients);     // Spring Security 6.4+
    interceptor.setClientRegistrationIdResolver(req -> "inventory-client"); // client-credentials registration
    return builder.baseUrl("https://inventory.internal").requestInterceptor(interceptor).build();
}

Q8. What's the difference between method security and URL security?

Short answer:

  • URL (request) security: configured in the SecurityFilterChain (authorizeHttpRequests). It's enforced by the AuthorizationFilter, before the request reaches the controller, based on the path, the HTTP method and the authorities. It's coarse-grained, central and cheap. For example, "/api/admin/** needs ADMIN".
  • Method security: @EnableMethodSecurity plus @PreAuthorize/@PostAuthorize/@PreFilter/@PostFilter (or @Secured, @RolesAllowed). It's enforced by an AOP proxy around the bean method. It's fine-grained, can use method arguments and return values in SpEL (ownership checks), and protects the service regardless of the entry point: REST, messaging or scheduled jobs.

Key points to cover:

  • Use both. URL rules as the outer fence, and method security for business rules.
  • Method security has the usual proxy caveats: self-invocation bypasses it, and it only applies to Spring beans.

Q9. What are Spring Security's core classes? Does it differ between Spring MVC and Spring Boot? Is there a starter?

Short answer: The core building blocks, in Spring Security 6:

  • SecurityFilterChain (a bean) and HttpSecurity: configure the ordered filter chain. The DelegatingFilterProxy/FilterChainProxy connect it to the servlet container.
  • AuthenticationManager (usually ProviderManager) and AuthenticationProviders, such as DaoAuthenticationProvider and JwtAuthenticationProvider.
  • UserDetailsService/UserDetails, and PasswordEncoder.
  • Authentication, SecurityContext and SecurityContextHolder (thread-local by default), plus SecurityContextRepository.
  • AuthorizationManager (URL and method authorisation), and GrantedAuthority.
  • AuthenticationEntryPoint (401) and AccessDeniedHandler (403).

Spring MVC vs Spring Boot:

  • With plain Spring MVC, you add the dependencies (spring-security-web, -config), register the filter (AbstractSecurityWebApplicationInitializer), and write all of the configuration yourself.
  • With Boot, spring-boot-starter-security brings everything, and auto-configures a default filter chain and user. Your SecurityFilterChain bean replaces the defaults. The core classes are the same.

Common trap: listing WebSecurityConfigurerAdapter as a core class. It was deprecated in 5.7, and removed in Spring Security 6 (Boot 3). Configure with SecurityFilterChain beans and the lambda DSL.

Q10. Your application needs stateless authentication for REST services. How would you implement JWT authentication with Spring Security? Describe the flow from login to accessing protected resources.

Short answer: The preferred design delegates token issuing to an authorization server (Keycloak, Okta, or Spring Authorization Server), and makes your API a resource server. If the API must issue tokens itself, the flow is:

  1. Login: the client POSTs its credentials to /auth/login over HTTPS. The AuthenticationManager authenticates them (DaoAuthenticationProvider + UserDetailsService + PasswordEncoder).
  2. Issue tokens: create a short-lived access JWT, signed with a private key (RS256 or ES256) that has a kid. It carries sub, the roles or scopes, iss, aud, exp and jti. Also issue a refresh token: opaque, stored hashed on the server, rotated on every use, and sent as an HttpOnly Secure SameSite cookie for browser clients.
  3. Call APIs: the client sends Authorization: Bearer <access-token>.
  4. Validate: BearerTokenAuthenticationFilter, from the resource-server support, extracts the token. A JwtDecoder checks the signature, algorithm, exp/nbf, iss and aud. A converter maps the claims to authorities, and the Authentication goes into the SecurityContext for this request only. No session is created.
  5. Authorise: URL rules and @PreAuthorize decide. The response is 401 for an invalid or expired token, and 403 for missing permission.
  6. Refresh: when the access token expires, the client calls /auth/refresh with the refresh token. The server verifies and rotates it; if an old one is reused, it detects the theft and revokes the whole token family.
  7. Logout or revoke: delete the refresh token. Access tokens die quickly; add a jti denylist if you need immediate cut-off.
@Bean
JwtDecoder jwtDecoder(RSAPublicKey publicKey) {
    NimbusJwtDecoder decoder = NimbusJwtDecoder.withPublicKey(publicKey).signatureAlgorithm(SignatureAlgorithm.RS256).build();
    decoder.setJwtValidator(JwtValidators.createDefaultWithValidators(      // default = exp/nbf (+ issuer via createDefaultWithIssuer)
            new JwtIssuerValidator("https://api.shopin.example"),
            new JwtClaimValidator<List<String>>("aud", aud -> aud != null && aud.contains("orders-api"))));
    return decoder;
}

Common traps:

  • Writing a hand-rolled JWT filter that only checks the signature, skipping expiry, audience and algorithm checks.
  • Storing tokens in localStorage: any XSS steals them. Prefer HttpOnly cookies, or a backend-for-frontend.
  • Using a weak HMAC secret shared across services.

Learn it in depth → OAuth2 & Social Login Basics

Follow-up questions this topic invites — and their answers

Q: When should CSRF protection be disabled? A: Only for APIs authenticated purely by headers (bearer tokens) that browsers don't attach automatically. If authentication uses cookies (sessions, or a JWT in a cookie), keep CSRF on (Spring's CookieCsrfTokenRepository for SPAs), or rely on SameSite plus custom-header checks with care.

Q: How do you rotate JWT signing keys without downtime? A: Publish the keys through a JWKS endpoint, identified by kid. Add the new key to the JWKS first, start signing with it, and keep the old public key published until every token signed with it has expired. Resource servers pick up the change from the cached JWKS automatically.

Q: How do you prevent IDOR (Broken Object Level Authorization)? A: Never trust IDs from the client alone. Check ownership or tenancy on every object access, in the service layer: @PostAuthorize("returnObject.ownerId == authentication.name"), or repository queries scoped by user or tenant (findByIdAndOwnerId). Test it explicitly.

Q: Where should rate limiting live? A: Mainly at the edge (the API gateway or WAF), per client, IP or token, so abuse is stopped cheaply. Add finer, per-user or per-operation limits in the service (Bucket4j with Redis) for expensive endpoints like login, OTP and search.

Previous

Custom Starters, DI, Testing & DevTools — Interview Questions

Next

Monolith Migration, Communication & Spring Cloud — Interview Questions

AI Tutor

Lesson: Securing REST APIs End to End — Interview Questions

Quick actions

AI responses can be inaccurate. Verify critical information.