https://github.com/clutcher/spring-security-exception-handler
A flexible library for handling Spring Security exceptions with customizable response formats, supporting both REST and GraphQL APIs.
https://github.com/clutcher/spring-security-exception-handler
exception-handler spring-boot spring-security
Last synced: 6 months ago
JSON representation
A flexible library for handling Spring Security exceptions with customizable response formats, supporting both REST and GraphQL APIs.
- Host: GitHub
- URL: https://github.com/clutcher/spring-security-exception-handler
- Owner: clutcher
- License: mit
- Created: 2025-06-16T11:58:58.000Z (7 months ago)
- Default Branch: main
- Last Pushed: 2025-07-02T17:50:10.000Z (6 months ago)
- Last Synced: 2025-07-02T18:33:12.789Z (6 months ago)
- Topics: exception-handler, spring-boot, spring-security
- Language: Java
- Homepage:
- Size: 65.4 KB
- Stars: 0
- Watchers: 0
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Spring Security Exception Handler
A flexible library for handling Spring Security exceptions with customizable response formats, supporting both REST and GraphQL APIs.
---
## Table of Contents
1. [Overview](#overview)
2. [Project Structure](#project-structure)
3. [Getting Started](#getting-started)
- [Installation](#installation)
- [Basic Usage](#basic-usage)
4. [Implementation Details](#implementation-details)
---
## Overview
By default, Spring Security uses its own `ExceptionTranslationFilter` which converts `AuthenticationException` and `AccessDeniedException` into empty responses with 401 and 403 status codes respectively. While this behavior is sufficient for many applications, there are cases when such behavior is not desired.
For example, in a microservice GraphQL federation environment, there is more value in returning JSON in a GraphQL-compatible format, allowing you to see access denied errors rather than just internal server errors.
**Spring Security Exception Handler** provides a clean and flexible way to handle security exceptions in Spring applications. It allows you to customize how authentication and authorization exceptions are handled and presented to clients, with built-in support for both standard REST APIs and GraphQL endpoints.
### Key Features
- Custom handling of Spring Security exceptions (`AuthenticationException` and `AccessDeniedException`)
- URL pattern-based routing of exceptions to appropriate handlers
- Built-in support for REST and GraphQL response formats
- Flexible builder API for creating custom exception handlers
- Spring Boot auto-configuration with sensible defaults
- Fully customizable through application properties
---
## Project Structure
This project consists of two main libraries:
- **`spring-security-exception-handler`** - Core library with exception handling logic and builder API
- **`spring-security-exception-handler-starter`** - Spring Boot starter with auto-configuration and property support
---
## Getting Started
### Installation
Add the starter dependency to your Spring Boot project:
#### Gradle
```kotlin
implementation("dev.clutcher.spring-security:spring-security-exception-handler-starter:1.0.0")
```
#### Maven
```xml
dev.clutcher.spring-security
spring-security-exception-handler-starter
1.0.0
```
### Basic Usage
The library provides auto-configuration that automatically sets up default exception handlers for both REST and GraphQL endpoints. Simply add the starter dependency to your project and the library will automatically inject a preconfigured instance of `SpringSecurityExceptionFilterConfigurer` through Spring Boot's auto-configuration mechanism.
The auto-configuration is enabled through `spring.factories` and `SpringSecurityExceptionHandlerAutoConfiguration`, which automatically registers the necessary components without requiring any manual configuration.
That's it! The library will automatically handle Spring Security exceptions with sensible defaults - no additional configuration required.
#### Manual Filter Configuration
If you need more control over the filter configuration or prefer explicit setup, you can manually create and configure the `SpringSecurityExceptionFilter` bean:
```java
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Autowired
private List exceptionHandlers;
@Bean
public SpringSecurityExceptionFilter springSecurityExceptionFilter() {
return new SpringSecurityExceptionFilter(exceptionHandlers);
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http,
SpringSecurityExceptionFilter exceptionFilter) throws Exception {
return http
.authorizeHttpRequests(authorize -> authorize
.requestMatchers("/public/**").permitAll()
.anyRequest().authenticated()
)
.addFilterBefore(exceptionFilter, ExceptionTranslationFilter.class)
.formLogin(withDefaults())
.build();
}
}
```
This approach gives you full control over when and how the filter is added to the security filter chain.
#### Property-Based Configuration
Configure exception handlers through application properties:
```yaml
dev:
clutcher:
security:
handlers:
default:
enabled: true
urls: ["/**"]
order: 100
graphql:
enabled: true
urls: ["/graphql"]
order: 0
custom:
enabled: true
urls: ["/api/v2/**"]
order: 50
```
#### Custom Exception Handler
Create custom exception handlers for specific URL patterns:
```java
@Configuration
public class CustomExceptionHandlerConfig {
@Bean
public SpringSecurityExceptionHandler apiV2ExceptionHandler() {
return SpringSecurityExceptionHandlerBuilder.builder()
.canHandle(new UrlMatchingPredicate(List.of("/api/v2/**")))
.handle(new ErrorResponseWritingConsumer(exception -> {
if (exception instanceof AuthenticationException) {
return new ErrorResponseWritingConsumer.ErrorResponse(
HttpServletResponse.SC_UNAUTHORIZED,
"{\"error\":\"Authentication required\",\"code\":\"AUTH_REQUIRED\"}"
);
}
if (exception instanceof AccessDeniedException) {
return new ErrorResponseWritingConsumer.ErrorResponse(
HttpServletResponse.SC_FORBIDDEN,
"{\"error\":\"Access denied\",\"code\":\"ACCESS_DENIED\"}"
);
}
return new ErrorResponseWritingConsumer.ErrorResponse(
HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
"{\"error\":\"Internal server error\"}"
);
}))
.order(50)
.build();
}
}
```
## Implementation Details
The Spring Security Exception Handler library is built around several key components that work together to provide flexible exception handling for Spring Security applications.
### Core Components
The library consists of the following main interfaces and classes:
- **`SpringSecurityExceptionFilter`** - Servlet filter that intercepts Spring Security exceptions and delegates to registered handlers.
- **`SpringSecurityExceptionHandler`** - Main interface for handling security exceptions. Implements `Ordered` to support priority-based handler selection.
- **`SpringSecurityExceptionHandlerBuilder`** - Fluent builder API for creating custom exception handlers with predicates and response writers.
- **`UrlMatchingPredicate`** - Predicate implementation for URL pattern matching using Spring's `AntPathMatcher`.
- **`ErrorResponseWritingConsumer`** - Consumer for writing structured error responses with customizable status codes and content.
- **`ExceptionMappingFunctions`** - Utility class providing pre-built exception mapping functions for common use cases.
### Exception Handling Flow
The exception handling process follows this sequence:
1. Spring Security's authentication or authorization mechanisms throw an `AuthenticationException` or `AccessDeniedException`
2. `SpringSecurityExceptionFilter` intercepts the exception before it reaches Spring Security's default `ExceptionTranslationFilter`
3. The filter iterates through all registered `SpringSecurityExceptionHandler` beans in priority order (based on the `getOrder()` method)
4. The first handler that returns `true` from its `canHandle(HttpServletRequest)` method processes the exception
5. The selected handler writes a custom response to the `HttpServletResponse` using its configured response writer
6. If no handler can process the request, the exception continues to Spring Security's default behavior
### Auto-Configuration
The Spring Boot starter provides auto-configuration through `SpringSecurityExceptionHandlerAutoConfiguration`, which:
- Registers default exception handlers for common scenarios (REST APIs, GraphQL endpoints)
- Configures handlers based on application properties under the `dev.clutcher.security` namespace
- Uses conditional beans to avoid conflicts with custom handler configurations
- Integrates seamlessly with Spring Security's filter chain through `SpringSecurityExceptionFilterConfigurer`
### Property-Based Configuration
The library supports comprehensive configuration through application properties:
```yaml
dev:
clutcher:
security:
handlers:
default:
enabled: true # Enable/disable the handler
urls: ["/**"] # URL patterns to match
order: 100 # Handler priority (lower = higher priority)
graphql:
enabled: true
urls: ["/graphql", "/graphiql"]
order: 0
```
Each handler configuration supports:
- **enabled** - Boolean flag to enable/disable the handler
- **urls** - List of URL patterns using Ant-style matching
- **order** - Integer defining handler priority (lower values have higher priority)
### Extensibility
The library is designed for extensibility through several extension points:
- **Custom Predicates** - Implement custom logic for determining when a handler should process a request
- **Custom Response Writers** - Create specialized response formats (XML, custom JSON structures, etc.)
- **Handler Composition** - Combine multiple handlers with different priorities and URL patterns
- **Integration Points** - Leverage Spring Boot's conditional configuration to adapt to different application contexts