diff --git a/spring-security/getting-started/SecureApplication/src/main/java/com/reflectoring/security/CustomHeaderValidatorFilter.java b/spring-security/getting-started/SecureApplication/src/main/java/com/reflectoring/security/CustomHeaderValidatorFilter.java new file mode 100644 index 0000000..8df59d9 --- /dev/null +++ b/spring-security/getting-started/SecureApplication/src/main/java/com/reflectoring/security/CustomHeaderValidatorFilter.java @@ -0,0 +1,37 @@ +package com.reflectoring.security; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.reflectoring.security.exception.CommonException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.util.StringUtils; +import org.springframework.web.filter.OncePerRequestFilter; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +public class CustomHeaderValidatorFilter extends OncePerRequestFilter { + + private static final Logger log = LoggerFactory.getLogger(CustomHeaderValidatorFilter.class); + + @Override + protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException { + String path = request.getRequestURI(); + return path.startsWith("/library/books/all"); + } + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { + log.info("Custom filter called..."); + if (StringUtils.isEmpty(request.getHeader("X-Application-Name"))) { + response.setStatus(HttpServletResponse.SC_FORBIDDEN); + response.setContentType("application/json"); + response.getOutputStream().println(new ObjectMapper().writeValueAsString(CommonException.headerError())); + } else { + filterChain.doFilter(request, response); + } + } +} diff --git a/spring-security/getting-started/SecureApplication/src/main/java/com/reflectoring/security/config/SecurityConfiguration.java b/spring-security/getting-started/SecureApplication/src/main/java/com/reflectoring/security/config/SecurityConfiguration.java index 7d6a1d0..444d865 100644 --- a/spring-security/getting-started/SecureApplication/src/main/java/com/reflectoring/security/config/SecurityConfiguration.java +++ b/spring-security/getting-started/SecureApplication/src/main/java/com/reflectoring/security/config/SecurityConfiguration.java @@ -1,5 +1,6 @@ package com.reflectoring.security.config; +import com.reflectoring.security.CustomHeaderValidatorFilter; import com.reflectoring.security.exception.UserAuthenticationErrorHandler; import com.reflectoring.security.exception.UserForbiddenErrorHandler; import org.springframework.boot.context.properties.EnableConfigurationProperties; @@ -15,6 +16,7 @@ import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.provisioning.InMemoryUserDetailsManager; import org.springframework.security.web.AuthenticationEntryPoint; import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; @Configuration @EnableWebSecurity @@ -44,9 +46,16 @@ public class SecurityConfiguration { .authenticationEntryPoint(userAuthenticationErrorHandler()) .accessDeniedHandler(new UserForbiddenErrorHandler())); + http.addFilterBefore(customHeaderValidatorFilter(), BasicAuthenticationFilter.class); + return http.build(); } + @Bean + public CustomHeaderValidatorFilter customHeaderValidatorFilter() { + return new CustomHeaderValidatorFilter(); + } + @Bean public WebSecurityCustomizer webSecurityCustomizer() { return (web) -> web.ignoring().antMatchers("/library/info"); diff --git a/spring-security/getting-started/SecureApplication/src/main/java/com/reflectoring/security/exception/CommonException.java b/spring-security/getting-started/SecureApplication/src/main/java/com/reflectoring/security/exception/CommonException.java index e6aa3e1..a24fdfd 100644 --- a/spring-security/getting-started/SecureApplication/src/main/java/com/reflectoring/security/exception/CommonException.java +++ b/spring-security/getting-started/SecureApplication/src/main/java/com/reflectoring/security/exception/CommonException.java @@ -6,8 +6,7 @@ import org.zalando.problem.AbstractThrowableProblem; import org.zalando.problem.StatusType; import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_EMPTY; -import static org.zalando.problem.Status.FORBIDDEN; -import static org.zalando.problem.Status.UNAUTHORIZED; +import static org.zalando.problem.Status.*; @JsonInclude(NON_EMPTY) @JsonIgnoreProperties({"stackTrace", "type", "title", "message", "localizedMessage", "parameters"}) @@ -25,5 +24,9 @@ public class CommonException extends AbstractThrowableProblem { return new CommonException(FORBIDDEN, "Forbidden"); } + public static CommonException headerError() { + return new CommonException(FORBIDDEN, "Missing Header"); + } + } diff --git a/spring-security/getting-started/SecureApplication/src/main/java/com/reflectoring/security/web/BookController.java b/spring-security/getting-started/SecureApplication/src/main/java/com/reflectoring/security/web/BookController.java index e681b04..79f1922 100644 --- a/spring-security/getting-started/SecureApplication/src/main/java/com/reflectoring/security/web/BookController.java +++ b/spring-security/getting-started/SecureApplication/src/main/java/com/reflectoring/security/web/BookController.java @@ -42,4 +42,6 @@ public class BookController { public ResponseEntity getInfo() { return ResponseEntity.ok().body(bookService.getLibraryInfo()); } + + }