{"id":29375373,"url":"https://github.com/clutcher/spring-security-exception-handler","last_synced_at":"2025-07-09T20:37:34.499Z","repository":{"id":302498607,"uuid":"1002955385","full_name":"clutcher/spring-security-exception-handler","owner":"clutcher","description":"A flexible library for handling Spring Security exceptions with customizable response formats, supporting both REST and GraphQL APIs.","archived":false,"fork":false,"pushed_at":"2025-07-02T17:50:10.000Z","size":67,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-07-02T18:33:12.789Z","etag":null,"topics":["exception-handler","spring-boot","spring-security"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/clutcher.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-06-16T11:58:58.000Z","updated_at":"2025-07-02T18:13:13.000Z","dependencies_parsed_at":"2025-07-02T18:46:32.829Z","dependency_job_id":null,"html_url":"https://github.com/clutcher/spring-security-exception-handler","commit_stats":null,"previous_names":["clutcher/spring-security-exception-handler"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/clutcher/spring-security-exception-handler","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clutcher%2Fspring-security-exception-handler","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clutcher%2Fspring-security-exception-handler/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clutcher%2Fspring-security-exception-handler/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clutcher%2Fspring-security-exception-handler/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/clutcher","download_url":"https://codeload.github.com/clutcher/spring-security-exception-handler/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clutcher%2Fspring-security-exception-handler/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264502997,"owners_count":23618676,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["exception-handler","spring-boot","spring-security"],"created_at":"2025-07-09T20:37:34.099Z","updated_at":"2025-07-09T20:37:34.476Z","avatar_url":"https://github.com/clutcher.png","language":"Java","readme":"# Spring Security Exception Handler\n\nA flexible library for handling Spring Security exceptions with customizable response formats, supporting both REST and GraphQL APIs.\n\n---\n\n## Table of Contents\n\n1. [Overview](#overview)\n2. [Project Structure](#project-structure)\n3. [Getting Started](#getting-started)\n    - [Installation](#installation)\n    - [Basic Usage](#basic-usage)\n4. [Implementation Details](#implementation-details)\n\n---\n\n## Overview\n\nBy 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.\n\nFor 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.\n\n**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.\n\n### Key Features\n\n- Custom handling of Spring Security exceptions (`AuthenticationException` and `AccessDeniedException`)\n- URL pattern-based routing of exceptions to appropriate handlers\n- Built-in support for REST and GraphQL response formats\n- Flexible builder API for creating custom exception handlers\n- Spring Boot auto-configuration with sensible defaults\n- Fully customizable through application properties\n\n---\n\n## Project Structure\n\nThis project consists of two main libraries:\n\n- **`spring-security-exception-handler`** - Core library with exception handling logic and builder API\n- **`spring-security-exception-handler-starter`** - Spring Boot starter with auto-configuration and property support\n\n---\n\n## Getting Started\n\n### Installation\n\nAdd the starter dependency to your Spring Boot project:\n\n#### Gradle\n```kotlin\nimplementation(\"dev.clutcher.spring-security:spring-security-exception-handler-starter:1.0.0\")\n```\n\n#### Maven\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003edev.clutcher.spring-security\u003c/groupId\u003e\n    \u003cartifactId\u003espring-security-exception-handler-starter\u003c/artifactId\u003e\n    \u003cversion\u003e1.0.0\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n### Basic Usage\n\nThe 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.\n\nThe auto-configuration is enabled through `spring.factories` and `SpringSecurityExceptionHandlerAutoConfiguration`, which automatically registers the necessary components without requiring any manual configuration.\n\nThat's it! The library will automatically handle Spring Security exceptions with sensible defaults - no additional configuration required.\n\n#### Manual Filter Configuration\n\nIf you need more control over the filter configuration or prefer explicit setup, you can manually create and configure the `SpringSecurityExceptionFilter` bean:\n\n```java\n@Configuration\n@EnableWebSecurity\npublic class SecurityConfig {\n\n    @Autowired\n    private List\u003cSpringSecurityExceptionHandler\u003e exceptionHandlers;\n\n    @Bean\n    public SpringSecurityExceptionFilter springSecurityExceptionFilter() {\n        return new SpringSecurityExceptionFilter(exceptionHandlers);\n    }\n\n    @Bean\n    public SecurityFilterChain filterChain(HttpSecurity http, \n                                         SpringSecurityExceptionFilter exceptionFilter) throws Exception {\n        return http\n            .authorizeHttpRequests(authorize -\u003e authorize\n                .requestMatchers(\"/public/**\").permitAll()\n                .anyRequest().authenticated()\n            )\n            .addFilterBefore(exceptionFilter, ExceptionTranslationFilter.class)\n            .formLogin(withDefaults())\n            .build();\n    }\n}\n```\n\nThis approach gives you full control over when and how the filter is added to the security filter chain.\n\n#### Property-Based Configuration\n\nConfigure exception handlers through application properties:\n\n```yaml\ndev:\n  clutcher:\n    security:\n      handlers:\n        default:\n          enabled: true\n          urls: [\"/**\"]\n          order: 100\n        graphql:\n          enabled: true\n          urls: [\"/graphql\"]\n          order: 0\n        custom:\n          enabled: true\n          urls: [\"/api/v2/**\"]\n          order: 50\n```\n\n#### Custom Exception Handler\n\nCreate custom exception handlers for specific URL patterns:\n\n```java\n@Configuration\npublic class CustomExceptionHandlerConfig {\n\n    @Bean\n    public SpringSecurityExceptionHandler apiV2ExceptionHandler() {\n        return SpringSecurityExceptionHandlerBuilder.builder()\n            .canHandle(new UrlMatchingPredicate(List.of(\"/api/v2/**\")))\n            .handle(new ErrorResponseWritingConsumer(exception -\u003e {\n                if (exception instanceof AuthenticationException) {\n                    return new ErrorResponseWritingConsumer.ErrorResponse(\n                        HttpServletResponse.SC_UNAUTHORIZED,\n                        \"{\\\"error\\\":\\\"Authentication required\\\",\\\"code\\\":\\\"AUTH_REQUIRED\\\"}\"\n                    );\n                }\n                if (exception instanceof AccessDeniedException) {\n                    return new ErrorResponseWritingConsumer.ErrorResponse(\n                        HttpServletResponse.SC_FORBIDDEN,\n                        \"{\\\"error\\\":\\\"Access denied\\\",\\\"code\\\":\\\"ACCESS_DENIED\\\"}\"\n                    );\n                }\n                return new ErrorResponseWritingConsumer.ErrorResponse(\n                    HttpServletResponse.SC_INTERNAL_SERVER_ERROR,\n                    \"{\\\"error\\\":\\\"Internal server error\\\"}\"\n                );\n            }))\n            .order(50)\n            .build();\n    }\n}\n```\n\n## Implementation Details\n\nThe Spring Security Exception Handler library is built around several key components that work together to provide flexible exception handling for Spring Security applications.\n\n### Core Components\n\nThe library consists of the following main interfaces and classes:\n\n- **`SpringSecurityExceptionFilter`** - Servlet filter that intercepts Spring Security exceptions and delegates to registered handlers.\n- **`SpringSecurityExceptionHandler`** - Main interface for handling security exceptions. Implements `Ordered` to support priority-based handler selection.\n- **`SpringSecurityExceptionHandlerBuilder`** - Fluent builder API for creating custom exception handlers with predicates and response writers.\n- **`UrlMatchingPredicate`** - Predicate implementation for URL pattern matching using Spring's `AntPathMatcher`.\n- **`ErrorResponseWritingConsumer`** - Consumer for writing structured error responses with customizable status codes and content.\n- **`ExceptionMappingFunctions`** - Utility class providing pre-built exception mapping functions for common use cases.\n\n### Exception Handling Flow\n\nThe exception handling process follows this sequence:\n\n1. Spring Security's authentication or authorization mechanisms throw an `AuthenticationException` or `AccessDeniedException`\n2. `SpringSecurityExceptionFilter` intercepts the exception before it reaches Spring Security's default `ExceptionTranslationFilter`\n3. The filter iterates through all registered `SpringSecurityExceptionHandler` beans in priority order (based on the `getOrder()` method)\n4. The first handler that returns `true` from its `canHandle(HttpServletRequest)` method processes the exception\n5. The selected handler writes a custom response to the `HttpServletResponse` using its configured response writer\n6. If no handler can process the request, the exception continues to Spring Security's default behavior\n\n### Auto-Configuration\n\nThe Spring Boot starter provides auto-configuration through `SpringSecurityExceptionHandlerAutoConfiguration`, which:\n\n- Registers default exception handlers for common scenarios (REST APIs, GraphQL endpoints)\n- Configures handlers based on application properties under the `dev.clutcher.security` namespace\n- Uses conditional beans to avoid conflicts with custom handler configurations\n- Integrates seamlessly with Spring Security's filter chain through `SpringSecurityExceptionFilterConfigurer`\n\n### Property-Based Configuration\n\nThe library supports comprehensive configuration through application properties:\n\n```yaml\ndev:\n  clutcher:\n    security:\n      handlers:\n        default:\n          enabled: true          # Enable/disable the handler\n          urls: [\"/**\"]          # URL patterns to match\n          order: 100             # Handler priority (lower = higher priority)\n        graphql:\n          enabled: true\n          urls: [\"/graphql\", \"/graphiql\"]\n          order: 0\n```\n\nEach handler configuration supports:\n- **enabled** - Boolean flag to enable/disable the handler\n- **urls** - List of URL patterns using Ant-style matching\n- **order** - Integer defining handler priority (lower values have higher priority)\n\n### Extensibility\n\nThe library is designed for extensibility through several extension points:\n\n- **Custom Predicates** - Implement custom logic for determining when a handler should process a request\n- **Custom Response Writers** - Create specialized response formats (XML, custom JSON structures, etc.)\n- **Handler Composition** - Combine multiple handlers with different priorities and URL patterns\n- **Integration Points** - Leverage Spring Boot's conditional configuration to adapt to different application contexts\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclutcher%2Fspring-security-exception-handler","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fclutcher%2Fspring-security-exception-handler","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclutcher%2Fspring-security-exception-handler/lists"}