Master Spring Security Exception Handling: From Authentication to Access Denied

This article explains the different exception types in Spring Security, how HTTP status codes map to authentication and authorization failures, and provides concrete implementations of AuthenticationEntryPoint and AccessDeniedHandler that return JSON responses, along with configuration tips for integrating them into a Spring Boot application.

Programmer DD
Programmer DD
Programmer DD
Master Spring Security Exception Handling: From Authentication to Access Denied

1. Introduction

Recently I have been busy and could not continue the Spring Security practical series . In my current project Spring Security needs handling of authentication and authorization exceptions, so I share the solution here.

2. Exceptions in Spring Security

Spring Security exceptions are mainly divided into two categories: authentication exceptions and authorization exceptions.

2.1 AuthenticationException

AuthenticationException

is thrown when an error occurs during user authentication. The main subclasses are shown in the diagram below.

According to the diagram, exceptions such as non‑existent user, locked account, expired credentials, or wrong password are all handled by AuthenticationException.

2.2 AccessDeniedException

AccessDeniedException

is thrown when a user is denied access to a protected resource. Like AuthenticationException, it also has specific subclasses, as shown in the following diagram.

The subclasses of AccessDeniedException are fewer, mainly related to CSRF exceptions and authorization service errors.

3. HTTP Status Codes for Authentication and Authorization

The HTTP protocol also defines response status codes for authentication and authorization.

3.1 401 Unauthorized

HTTP 401 indicates that the request requires authentication. When a 401 error appears, it means the username, password, or both are invalid (e.g., wrong credentials, disabled account, locked account). This corresponds to an AuthenticationException.

3.2 403 Forbidden

HTTP 403 indicates that the client is authenticated but does not have permission to access the requested resource. This corresponds to an AccessDeniedException.

4. Exception Handling in Spring Security

In the WebSecurityConfigurerAdapter configuration, HttpSecurity provides the exceptionHandling() method, which creates an ExceptionHandlingConfigurer. This configurer offers two useful interfaces:

AuthenticationEntryPoint – handles AuthenticationException uniformly.

AccessDeniedHandler – handles AccessDeniedException uniformly.

Implementing and configuring these two handlers allows unified custom handling of Spring Security authentication and authorization exceptions.

4.1 Implementing AuthenticationEntryPoint

Return a JSON response:

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.http.MediaType;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;

public class SimpleAuthenticationEntryPoint implements AuthenticationEntryPoint {
    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException)
            throws IOException, ServletException {
        // custom business logic
        HashMap<String, String> map = new HashMap<>(2);
        map.put("uri", request.getRequestURI());
        map.put("msg", "Authentication failed");
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        response.setCharacterEncoding("utf-8");
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
        ObjectMapper objectMapper = new ObjectMapper();
        String resBody = objectMapper.writeValueAsString(map);
        PrintWriter printWriter = response.getWriter();
        printWriter.print(resBody);
        printWriter.flush();
        printWriter.close();
    }
}

4.2 Implementing AccessDeniedHandler

Also return a JSON response:

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.http.MediaType;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;

public class SimpleAccessDeniedHandler implements AccessDeniedHandler {
    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException)
            throws IOException, ServletException {
        // custom business logic
        HashMap<String, String> map = new HashMap<>(2);
        map.put("uri", request.getRequestURI());
        map.put("msg", "Authorization failed");
        response.setStatus(HttpServletResponse.SC_FORBIDDEN);
        response.setCharacterEncoding("utf-8");
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
        ObjectMapper objectMapper = new ObjectMapper();
        String resBody = objectMapper.writeValueAsString(map);
        PrintWriter printWriter = response.getWriter();
        printWriter.print(resBody);
        printWriter.flush();
        printWriter.close();
    }
}

4.3 Personal Practice Recommendation

I recommend always returning HTTP 200 and placing the actual 401/403 status inside the response body map, because browsers display error pages for non‑200 status codes.

4.4 Configuration

After implementing the two interfaces, configure them in WebSecurityConfigurerAdapter:

http.exceptionHandling()
    .accessDeniedHandler(new SimpleAccessDeniedHandler())
    .authenticationEntryPoint(new SimpleAuthenticationEntryPoint());
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaException HandlingAuthorizationspring-security
Programmer DD
Written by

Programmer DD

A tinkering programmer and author of "Spring Cloud Microservices in Action"

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.