Spring boot Interceptor dont show #ControllerAdvice errorhandler? - java

Implemetation: Im trying to implementin project with Interceptor but the Error handling in showing only in Terminal which is good but i need also to show in restapi in postman and its showing empty.
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
public class WebInterceptor implements HandlerInterceptor {
private Logger logger = LoggerFactory.getLogger(WebInterceptor.class);
#Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
logger.error("WebInterceptor preHandle is now logged");
return true;
}
#Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
logger.error("WebInterceptor posthandle is now logged");
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
}
#Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
logger.error("WebInterceptor afterCompletion is now logged");
HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
}
}
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
#Configuration
public class AppConfig implements WebMvcConfigurer{
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new WebInterceptor()).addPathPatterns("/cart/**").order(1);
registry.addInterceptor(new WebInterceptor()).addPathPatterns("/product/**").order(2);
}
}
import com.kongapigateway.KongAPIgateway.ModelException.DATE_FORMAT_ERROR;
import com.kongapigateway.KongAPIgateway.ModelException.ProductExecption;
import com.kongapigateway.KongAPIgateway.ModelException.ProductIDnotFound;
import com.kongapigateway.KongAPIgateway.ModelException.ProductValueNotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
#RestControllerAdvice
public class WEbAspectExceptionConfig {
private Logger logger = LoggerFactory.getLogger(WEbAspectExceptionConfig.class);
#ExceptionHandler(ProductValueNotNull.class)
#ResponseStatus
public void handle(ProductValueNotNull e) {
logger.error(e.getMessage());
}
#ExceptionHandler(DATE_FORMAT_ERROR.class)
#ResponseStatus
public void handle2(DATE_FORMAT_ERROR e) {
logger.error(e.getMessage());
}
#ExceptionHandler(ProductExecption.class)
#ResponseStatus
public void handle2(ProductExecption e) {
logger.error(e.getMessage());
}
#ExceptionHandler(ProductIDnotFound.class)
#ResponseStatus
public void handle2(ProductIDnotFound e) {
logger.error(e.getMessage());
}
}
Terminal Output:
This is the error handling message: Please input all field
kongapigateway | 2022-06-07 11:21:33.149 INFO 1 --- [nio-8095-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 1 ms
kongapigateway | 2022-06-07 11:21:33.161 ERROR 1 --- [nio-8095-exec-1] c.k.K.Interceptor.WebInterceptor : WebInterceptor preHandle is now logged
kongapigateway | 2022-06-07 11:21:33.277 ERROR 1 --- [nio-8095-exec-1] c.k.K.AOP.WEbAspectExceptionConfig : Please input all field
kongapigateway | 2022-06-07 11:21:33.277 ERROR 1 --- [nio-8095-exec-1] c.k.K.Interceptor.WebInterceptor : WebInterceptor afterCompletion is now logged
Postman api error handler is Empty
Shown here

Kindly disregard this Post Question.
I used Spring AOP #Around for customize exception.
Thank you.

Related

Handling Errors in a Spring Boot Controller

I want to process an error in the controller, I looked at how it is done, but the error is not processed, tell me what's wrong.
Controller
#ControllerAdvice
public class ErrorController {#ExceptionHandler(ResourceNotFoundException.class)
public String notFound(){
System.out.println("Hello");
return "error/not_found";
}
}
Exeption
public final class ResourceNotFoundException extends RuntimeException {
ResourceNotFoundException(String message){
super(message);
}
}
Filter where I return an error
package com.example.demo.HttpErrorConfig;
import com.example.demo.Controllers.web.ErrorController;
import com.example.demo.Exception.ResourceNotFoundException;
import org.springframework.web.filter.GenericFilterBean;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class HttpStatusFilter extends GenericFilterBean {
private final HttpStatusProvider httpStatusProvider =
new HttpStatusProvider();
#Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
int status = httpStatusProvider.getStatus((HttpServletResponse) servletResponse);
filterChain.doFilter(servletRequest,servletResponse);
if (status==404){
System.out.println(404);
throw new ResourceNotFoundException("e");
}
}
}

How can we postHandle an exception in HandlerInterceptorAdapter?

I am currently trying to implement a customized error handler for spring boot and I have done it with the following:
public class ExceptionHandler extends HandlerInterceptorAdapter {
public static Logger log = LoggerFactory.getLogger(LoggingInterceptor.class);
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, #Nullable ModelAndView modelAndView) throws Exception {
try {
log.info("Service {} Calling {} on {} finished with status {}",request.getRemoteUser(), request.getMethod(), request.getRequestURI(), HttpStatus.valueOf(response.getStatus()));
} catch (Exception e) {
// Do nothing
} finally {
log.error("[Spring Boot Interceptor] {} returned with {}", handler, HttpStatus.valueOf(response.getStatus()));
}
}
Somehow this does not work, and the exception is still thrown to the client, is there some way to catch the exception thrown by the method and ignore it for example.
A good way to manage the exception is using #ControllerAdvice, using this you may handle any kind of exception and customize the response as required.
As said in the comment, you have to add InterceptorRegistry to register the interceptor.
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
#Configuration
public class WebConfig implements WebMvcConfigurer {
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new Interceptor()).addPathPatterns("/**");
}
}
The catch block inside postHandle will only be executed if an exception occurred inside the try-catch block as below,
#Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, #Nullable ModelAndView modelAndView) throws Exception {
try {
int error = 1/0;
} catch (Exception e) {
log.info("Exception will be handled inside catch block");
}
}
Now let's explore the #ControllerAdvice to manage the exception within the application. These two APIs will generate the exceptions and we will manage the exceptions using #ExceptionHandler
#GetMapping("/exception/404")
public void generateResourceNotFound() {
throw new ResourceNotFoundException("resource not found");
}
#GetMapping("/exception/403")
public void generateAccessDenied() {
throw new AccessDeniedException("access denied");
}
GlobalExceptionHandler.java
import com.learning.annotations.controller.ResourceNotFoundException;
import com.learning.annotations.dto.ErrorResponseDTO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
#ControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
public Logger log = LoggerFactory.getLogger(Interceptor.class);
#ExceptionHandler(AccessDeniedException.class)
public ResponseEntity<ErrorResponseDTO> handleAccessDeniedException(AccessDeniedException ex, WebRequest request) {
ErrorResponseDTO response = new ErrorResponseDTO();
response.setError(ex.getMessage());
response.setMessage("You don't have authority to access the resource");
return new ResponseEntity<>(response, HttpStatus.FORBIDDEN);
}
#ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<ErrorResponseDTO> handleResourceNotFoundException(ResourceNotFoundException ex, WebRequest request) {
ErrorResponseDTO response = new ErrorResponseDTO();
response.setError(ex.getMessage());
response.setMessage("Resource might be moved temporary or not available");
return new ResponseEntity<>(response, HttpStatus.NOT_FOUND);
}
}
To customize the response we can create error response DTO as follows,
import lombok.Data;
#Data
public class ErrorResponseDTO {
private String message;
private String error;
}

How to handle UsernameNotFoundException spring security

How to handle UsernameNotFoundException ?
In spring security when username not found the UserDetailsService implementation throws a UsernameNotFoundException. For example like this:
#Override
#Transactional
public UserDetails loadUserByUsername(java.lang.String username) throws UsernameNotFoundException {
logger.info("Load user by username: {}", username);
User user = userRepository.findUserByUsername(username).orElseThrow(
() -> new UsernameNotFoundException("User Not Found with -> username or email: " + username));
return UserPrinciple.build(user);
}
I would like to build a custom "User not found REST response".
How should I catch/handle this exception? I have implemented a handler method in the WebSecurityConfigurerAdapter implementation the handler:
private static void handleException(HttpServletRequest req, HttpServletResponse rsp, AuthenticationException e)
throws IOException {
PrintWriter writer = rsp.getWriter();
writer.println(new ObjectMapper().writeValueAsString(new AuthResponse("", null, null, null, null,
"Authentication failed.", false)));
rsp.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
}
But this method should wait for an AuthenticationException exception which, and during runtime the type of the exception is java.lang.NullPointerException so I'm not able to cast or retrieve the the initial UsernameNotFoundException.
Any advice would be appreciated.
Many many regards :).
Security layer comes before anything in the controllers and #ControllerAdvice.
Hence #ControllerAdvice isn't an option since UsernameNotFoundException which is a subclass of AuthenticationException is thrown during authenticaton, making your exception handlers in #ControllerAdvice unreachable.
You can only use #ControllerAdvice and ResponseEntityExceptionHandler if you are throwing UsernameNotFoundException inside controller or any others beans referenced from the controllers.
Here is my suggestion - that you implement AuthenticationFailureHandler and use it with AuthenticationFilter that you are using for your security configuration.
Spring boot security comes with about 4 handler interfaces for security related issues
AccessDeniedHandler - this handles issues like when a user not having required roles.
AuthenticationEntryPoint - this handles issues like when a user tries to access a resource without appropriate authentication elements.
AuthenticationFailureHandler - this handles issues like when a user is not found(i.e. UsernameNotFoundException) or other exceptions thrown inside authentication provider. In fact, this handles other authentication exceptions that are not handled by AccessDeniedException and AuthenticationEntryPoint.
AuthenticationSuccessHandler - this helps to do stuff like redirection after a user is successfully authenticated.
See the following example snippets for the implementation of all the 4 interfaces. Please customize these to your taste.
AccessDeniedHandler implementation
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
#Component
public class RestAccessDeniedHandler implements AccessDeniedHandler {
#Override
public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException e) throws IOException, ServletException {
Map<String,Object> response = new HashMap<>();
response.put("status","34");
response.put("message","unauthorized api access");
//httpServletResponse.setStatus(HttpServletResponse.SC_FORBIDDEN);
httpServletResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
OutputStream out = httpServletResponse.getOutputStream();
ObjectMapper mapper = new ObjectMapper();
mapper.writerWithDefaultPrettyPrinter().writeValue(out,response);
//mapper.writeValue(out, response);
out.flush();
}
}
AuthenticationEntryPoint Implementation
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
#Component
public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint {
#Override
public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
Map<String,Object> response = new HashMap<>();
response.put("status","34");
response.put("message","unauthorized access");
httpServletResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
OutputStream out = httpServletResponse.getOutputStream();
ObjectMapper mapper = new ObjectMapper();
mapper.writerWithDefaultPrettyPrinter().writeValue(out, response);
out.flush();
}
}
AuthenticationFailureHandler implementation
package com.ibiller.webservices.security;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
#Component
public class RestAuthenticationFailureHandler implements AuthenticationFailureHandler
{
#Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse httpServletResponse,
AuthenticationException ex) throws IOException, ServletException
{
Map<String,Object> response = new HashMap<>();
response.put("status","34");
response.put("message","unauthorized access");
httpServletResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
OutputStream out = httpServletResponse.getOutputStream();
ObjectMapper mapper = new ObjectMapper();
mapper.writerWithDefaultPrettyPrinter().writeValue(out, response);
out.flush();
}
}
AuthenticationSuccessHandler implementation
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
#Component
public class RestSuccessHandler implements AuthenticationSuccessHandler {
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException {
Set<String> roles =
AuthorityUtils.authorityListToSet(authentication.getAuthorities());
if (roles.contains("ROLE_ADMIN")) {
//do something
}
}
}
This is the Security configuration that extends WebSecurityConfigurerAdapter that connects everything together.
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.AnonymousAuthenticationFilter;
import org.springframework.security.web.authentication.HttpStatusEntryPoint;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.OrRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(
prePostEnabled = true,
securedEnabled = true,
jsr250Enabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private static final RequestMatcher PROTECTED_URLS = new OrRequestMatcher(
new AntPathRequestMatcher("/v1/**"),new AntPathRequestMatcher("/admin/**")
);
AuthenticationProvider provider;
public SecurityConfiguration(final AuthenticationProvider authenticationProvider) {
super();
this.provider=authenticationProvider;
}
#Override
protected void configure(final AuthenticationManagerBuilder auth) {
auth.authenticationProvider(provider);
}
#Override
public void configure(final WebSecurity webSecurity) {
webSecurity.ignoring().antMatchers("/info/**");//url that will be ignored
}
#Override
public void configure(HttpSecurity http) throws Exception {
http.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.exceptionHandling()
.accessDeniedHandler(accessDeniedHandler())
.authenticationEntryPoint(authenticationEntryPoint())
.and()
.authenticationProvider(provider)
.addFilterBefore(authenticationFilter(), AnonymousAuthenticationFilter.class)
.authorizeRequests()
.antMatchers("/v1/**").hasRole("API")
.antMatchers("/admin/**").hasAnyRole("SUPER_ADMIN","ADMIN")
.and()
.csrf().disable()
.formLogin().disable()
.httpBasic().disable()
.logout().disable();
}
#Bean
AuthenticationFilter authenticationFilter() throws Exception {
final AuthenticationFilter filter = new AuthenticationFilter(PROTECTED_URLS);
filter.setAuthenticationManager(authenticationManager());
filter.setAuthenticationSuccessHandler(successHandler());
filter.setAuthenticationFailureHandler(authenticationFailureHandler());
return filter;
}
#Bean
RestAccessDeniedHandler accessDeniedHandler() {
return new RestAccessDeniedHandler();
}
#Bean
RestAuthenticationEntryPoint authenticationEntryPoint() {
return new RestAuthenticationEntryPoint();
}
#Bean
RestAuthenticationFailureHandler authenticationFailureHandler(){
return new RestAuthenticationFailureHandler();
}
#Bean
RestSuccessHandler successHandler(){
return new RestSuccessHandler();
}
}
I don't know the structure of your project, but a usual solution in this case is using #ControllerAdvice mechanism (separated class or in controller):
#ControllerAdvice
public class CustomExceptionHandler {
#ExceptionHandler(value = UsernameNotFoundException.class)
public ResponseEntity handle(final UsernameNotFoundException exception) {
...//set headers, response attributes and response body
}
}
In the class that inherits from UsernamePasswordAuthenticationFilter you have to override the method unsuccessfulAuthentication
It calls the super class method, but what it does it's it redirects to another context of error, which makes the Authorization filter activates.
Instead, just fill the request information as your client is expecting (Json in my case)
#Override
protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse res, AuthenticationException failed) throws IOException, ServletException {
res.addHeader("Access-Control-Allow-Origin", "*");
res.setStatus(HttpServletResponse.SC_OK);
ObjectMapper mapper = new ObjectMapper();
ObjectNode message = mapper.createObjectNode();
message.put("success", false);
message.put("message", "Invalid credentials");
String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(message);
PrintWriter out = res.getWriter();
res.setContentType("application/json");
res.setCharacterEncoding("UTF-8");
out.print(json);
out.flush();
}

How to disallow TRACE http method in spring boot actuator

I have a server on port = 8078 and spring boot actuator on port = 8081.I want to disable TRACE Http method on both. I already create customizer bean(see below). But with this bean I disallowed only Trace on 8078. It's looks like actuator doesn't see this bean. How to disable TRACE http method on management server?
#ManagementContextConfiguration
public class CustomUndertowCustomizer {
#Bean
public WebServerFactoryCustomizer<UndertowServletWebServerFactory> undertowCustomizer() {
return (factory) ->
factory.addDeploymentInfoCustomizers(deploymentInfo ->
deploymentInfo.addInitialHandlerChainWrapper(handler -> {
HttpString[] disallowedHttpMethods = {HttpString.tryFromString("TRACE"),
HttpString.tryFromString("TRACK")};
return new DisallowedMethodsHandler(handler, disallowedHttpMethods);
}));
}
}
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
#Component
public class Filter extends OncePerRequestFilter {
#Override
protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain filterChain)
{
try {
if (req.getMethod().equals("TRACE")) {
res.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
} else {
filterChain.doFilter(req, res);
}
} catch(Exception e){}
}
}

request.getRequestURI always returns "/error"

In a webapp I'm building using Spring Boot & MVC and am trying to deny access to for all URL's except /signin for users that are not logged in. To achieve this I've setup an implementation of HandlerInterceptor where the preHandler should route all non-valid requests to the /signin page.
The setup:
LoginViewController
package com.controller;
import com.model.UserDao;
import com.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
#Controller
#RequestMapping(value = "/signin")
#SessionAttributes("username")
public class LoginViewController {
#Autowired
private UserService userService;
#RequestMapping(method = RequestMethod.GET)
public ModelAndView showLoginForm(){
return new ModelAndView("login");
}
#RequestMapping(method = RequestMethod.POST)
public ModelAndView verifyLogin(HttpServletRequest request, HttpSession session) {
ModelAndView modelAndView;
String username = request.getParameter("username");
// if login fails, set reload login page
if (userService.verifyUserLogin(username,request.getParameter("password")) == null){
modelAndView = new ModelAndView("login");
modelAndView.addObject("login_failed", true);
} else {
modelAndView = new ModelAndView("index");
session.setAttribute("username", username);
}
return modelAndView;
}
}
AccessInterceptor
package com.spring.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import java.util.ArrayList;
public class AccessInterceptor implements HandlerInterceptor {
#Override
public boolean preHandle(
HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
System.out.println(request.getRequestURI());
try {
if (!request.getRequestURI().endsWith("/signin")) {
if (request.getSession()
.getAttribute("username") == null) {
response.sendRedirect(request.getContextPath() + "/signin");
return false;
}
}
} catch (Exception e) {
System.out.println(e.getMessage());
}
return true;
}
#Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("Post-handle");
}
#Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println("After completion handle");
}
}
WebApplicationConfig
package com.spring;
import com.spring.interceptor.AccessInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.*;
#Configuration
#EnableWebMvc
public class WebApplicationConfig extends WebMvcConfigurerAdapter {
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(
new AccessInterceptor()).
addPathPatterns("/**").
excludePathPatterns("/signin/**").
excludePathPatterns("/static/**");
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
}
WebApplicationInitializer
package com.spring;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletRegistration;
public class MyWebAppInitializer implements WebApplicationInitializer {
#Override
public void onStartup(ServletContext container) {
// Create the 'root' Spring application context
AnnotationConfigWebApplicationContext rootContext =
new AnnotationConfigWebApplicationContext();
rootContext.register(WebApplicationConfig.class);
// Manage the lifecycle of the root application context
container.addListener(new ContextLoaderListener(rootContext));
// Create the dispatcher servlet's Spring application context
AnnotationConfigWebApplicationContext dispatcherContext =
new AnnotationConfigWebApplicationContext();
dispatcherContext.register(MyWebAppInitializer.class);
// Register and map the dispatcher servlet
ServletRegistration.Dynamic dispatcher = container.addServlet("dispatcherServlet", new DispatcherServlet(rootContext));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/*");
dispatcher.addMapping("*.css");
dispatcher.addMapping("*.eot");
dispatcher.addMapping("*.svg");
dispatcher.addMapping("*.ttf");
dispatcher.addMapping("*.woff");
dispatcher.addMapping("*.map");
dispatcher.addMapping("*.js");
dispatcher.addMapping("*.ico");
}
}
Now the problem is that the System.out.println(request.getRequestURI()) in AccessInterceptor always prints /error. So the request is always redirected even when calling /signin. Another interesting thing is that no CSS or other static resources are rendered, even with the dispacher mapping configured.
Any Ideas?
if you missing your payload, the api url couldn't recognize. at least put something
I also met this problem,in WebLogIntercept(your MyWebAppInitializer) class
I solved this problem using the following code
add this two func
private Class getClassByName(Class classObject, String name){
Map<Class,List<Field>> fieldMap = new HashMap<>();
Class returnClass = null;
Class tempClass = classObject;
while (tempClass != null) {
fieldMap.put(tempClass,Arrays.asList(tempClass .getDeclaredFields()));
tempClass = tempClass.getSuperclass();
}
for(Map.Entry<Class,List<Field>> entry: fieldMap.entrySet()){
for (Field f : entry.getValue()) {
if(f.getName().equals(name)){
returnClass = entry.getKey();
break;
}
}
}
return returnClass;
}
private Object findCoyoteRequest(Object request) throws Exception {
Class a = getClassByName(request.getClass(),"request");
Field request1 = a.getDeclaredField("request");
request1.setAccessible(true);
Object b = request1.get(request);
if(getClassByName(b.getClass(),"coyoteRequest") == null){
return findCoyoteRequest(b);
}else{
return b;
}
and use this code
Object a = findCoyoteRequest(request);
Field coyoteRequest = a.getClass().getDeclaredField("coyoteRequest");
coyoteRequest.setAccessible(true);
Object b = coyoteRequest.get(a);
Field uriMB = b.getClass().getDeclaredField("uriMB");
uriMB.setAccessible(true);
MessageBytes c = (MessageBytes)uriMB.get(b);
System.out.println(c.getString());
c.getString() is realuri
my english is not good,Hope useful
Disabling CFR worked for me
See https://www.baeldung.com/spring-security-csrf
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
}
I have the same function to implement as you. And I finally found that there was nothing wrong with this function. The "/error" request actually exists, maybe sent by the servlet container or whatever(i don't know). It exists to show you the exception on the browser.
When I put "/error" to my white-list(I also put paths like "/login" which don't need the authority), the e.printStackTrace(); information just show on the browser.
sometimes,you can try rebuild project,here is my code:
if(request.getRequestURI().startsWith("/user/")) {return true;}
it always return "/error"

Categories