From 8205168bcef684d6f2ab14ab5f208dcde09a88d5 Mon Sep 17 00:00:00 2001 From: Takiguchi Date: Thu, 8 Aug 2019 20:51:53 +0200 Subject: [PATCH] Add a "JSONified" error management. --- .../core/config/CustomErrorController.java | 58 +++++++++++++++++++ .../RestAuthenticationEntryPoint.java | 2 +- .../core/security/SecurityConfiguration.java | 25 ++++---- src/main/resources/application.yml | 3 + 4 files changed, 76 insertions(+), 12 deletions(-) create mode 100644 src/main/java/org/codiki/core/config/CustomErrorController.java diff --git a/src/main/java/org/codiki/core/config/CustomErrorController.java b/src/main/java/org/codiki/core/config/CustomErrorController.java new file mode 100644 index 0000000..f5119c2 --- /dev/null +++ b/src/main/java/org/codiki/core/config/CustomErrorController.java @@ -0,0 +1,58 @@ +package org.codiki.core.config; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.web.servlet.error.ErrorAttributes; +import org.springframework.boot.web.servlet.error.ErrorController; +import org.springframework.util.Assert; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.context.request.RequestAttributes; +import org.springframework.web.context.request.ServletRequestAttributes; +import org.springframework.web.context.request.ServletWebRequest; + +import javax.servlet.http.HttpServletRequest; +import java.util.Map; + +/** + * Controller that catch errors from spring rest or spring security and others, and transform them to JSON response. + */ +@RestController +@RequestMapping("/error") +public class CustomErrorController implements ErrorController { + + private final ErrorAttributes errorAttributes; + + @Autowired + public CustomErrorController(ErrorAttributes errorAttributes) { + Assert.notNull(errorAttributes, "ErrorAttributes must not be null"); + this.errorAttributes = errorAttributes; + } + + @Override + public String getErrorPath() { + return "/error"; + } + + @RequestMapping + public Map error(HttpServletRequest request){ + Map body = getErrorAttributes(request, getTraceParameter(request)); + String trace = (String) body.get("trace"); + if(trace != null){ + String[] lines = trace.split("\n\t"); + body.put("trace", lines); + } + return body; + } + + private boolean getTraceParameter(HttpServletRequest request) { + String parameter = request.getParameter("trace"); + if (parameter == null) { + return false; + } + return !"false".equals(parameter.toLowerCase()); + } + + private Map getErrorAttributes(HttpServletRequest request, boolean includeStackTrace) { + return errorAttributes.getErrorAttributes(new ServletWebRequest(request), includeStackTrace); + } +} \ No newline at end of file diff --git a/src/main/java/org/codiki/core/security/RestAuthenticationEntryPoint.java b/src/main/java/org/codiki/core/security/RestAuthenticationEntryPoint.java index de0d1e2..65248cb 100755 --- a/src/main/java/org/codiki/core/security/RestAuthenticationEntryPoint.java +++ b/src/main/java/org/codiki/core/security/RestAuthenticationEntryPoint.java @@ -23,6 +23,6 @@ public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint { @Override public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException { - response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized"); + response.sendError(HttpServletResponse.SC_UNAUTHORIZED); } } diff --git a/src/main/java/org/codiki/core/security/SecurityConfiguration.java b/src/main/java/org/codiki/core/security/SecurityConfiguration.java index 7f27cd6..8a7317e 100755 --- a/src/main/java/org/codiki/core/security/SecurityConfiguration.java +++ b/src/main/java/org/codiki/core/security/SecurityConfiguration.java @@ -45,27 +45,30 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() + // Permits all .antMatchers( "/api/account/login", "/api/account/logout", "/api/account/signin" ).permitAll() + .antMatchers( + HttpMethod.GET, + "/api/categories", + "/api/images", + "/api/posts", + "/api/categories/**", + "/api/images/**", + "/api/posts/**" + ).permitAll() .antMatchers( "/api/images/uploadAvatar", "/api/images/myImages", - "/api/posts/myPosts", "/api/account/changePassword", - "/api/account/" + "/api/account/", + "/api/posts/myPosts", + "/api/posts/preview", + "/api/posts/" ).authenticated() - .antMatchers( - HttpMethod.GET, - "/api/categories", - "/api/images", - "/api/posts", - "/api/categories/**", - "/api/images/**", - "/api/posts/**" - ).permitAll() .anyRequest().permitAll() .and() // Allow to avoid login form at authentication failure from Angular app diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 5202365..0dd5724 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -21,6 +21,9 @@ logging: server: # use-forward-headers=true + error: + whitelabel: + enabled: false # Disable html error responses. port: 8080 # ssl: # key-store: /home/takiguchi/Developpement/Java/codiki/keystore.p12