Learn to return access denied response with error details in jSON format, from a REST API, in cases where principal should be pre-authenticated but is received null
in AbstractPreAuthenticatedProcessingFilter
.
1. Add Custom AuthenticationEntryPoint
This class is used by ExceptionTranslationFilter
to commence an authentication scheme. In case you are using AbstractPreAuthenticatedProcessingFilter
to handle pre-authenticated authentication requests as shown in custom token authentication example, by default all unauthenticated users are redirected to the default access denied page i.e. Http403ForbiddenEntryPoint
.
The default behavior displays a access denied HTML page.
We can change the behavior defining our own custom AuthenticationEntryPoint
. This authentication entry point is added to exceptionHandling() configuration.
- ExceptionTranslationFilter is used to catch any Spring Security exceptions so that either an HTTP error response can be returned or an appropriate
AuthenticationEntryPoint
can be launched. - The AuthenticationEntryPoint will be called if the user requests a secure HTTP resource but they are not authenticated. This does the job of presenting the appropriate response to the user so that authentication can begin.
In given configuration, we are securing all URLs starting with "/api"
.
httpSecurity. antMatcher("/api/**") .csrf() .disable() .sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() .addFilter(filter) /*.addFilterBefore(new ExceptionTranslationFilter( new Http403ForbiddenEntryPoint()), filter.getClass() )*/ .authorizeRequests() .anyRequest() .authenticated(); //Exception handling configuration httpSecurity .exceptionHandling() .authenticationEntryPoint((request, response, e) -> { response.setContentType("application/json;charset=UTF-8"); response.setStatus(HttpServletResponse.SC_FORBIDDEN); response.getWriter().write(new JSONObject() .put("timestamp", LocalDateTime.now()) .put("message", "Access denied") .toString()); });
Please do not use AccessDeniedHandler as it is only applies to authenticated users where user does not required roles.
2. Demo
2.1. Without auth token
HTTP POST http://localhost:8080/SpringRestExample/api/rest/employee-management/employees/1 Headers: Content-Type application/json
Response code - 403 Forbidden { "message" : "Access denied", "timestamp" : "2019-05-03T23:59:52.103" }
2.2. With incorrect auth token
HTTP POST http://localhost:8080/SpringRestExample/api/rest/employee-management/employees/1 Headers: Content-Type application/json AUTH_API_KEY 123456
Response code - 403 Forbidden { "message" : "Access denied", "timestamp" : "2019-05-04T00:04:15.457" }
2.2. With CORRECT auth token
HTTP POST http://localhost:8080/SpringRestExample/api/rest/employee-management/employees/1 Headers: Content-Type application/json AUTH_API_KEY abcd123456
Response code - 200 OK { //API response body }
Drop me your questions related to convert access denied response from an Spring REST API to JSON response using custom authenticationEntryPoint.
Happy Learning !!