Merge pull request #43 from HideyoshiSolutions/devel
Devel - Fixes Auth Filter for Health Checker
This commit is contained in:
@@ -67,6 +67,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
|||||||
|
|
||||||
http.authorizeRequests()
|
http.authorizeRequests()
|
||||||
.antMatchers("/session/**").permitAll()
|
.antMatchers("/session/**").permitAll()
|
||||||
|
.and().authorizeRequests().antMatchers("/health").permitAll()
|
||||||
.and().authorizeRequests().antMatchers("/user/signup").permitAll()
|
.and().authorizeRequests().antMatchers("/user/signup").permitAll()
|
||||||
.and().authorizeRequests().antMatchers("/user/oauth/**").permitAll()
|
.and().authorizeRequests().antMatchers("/user/oauth/**").permitAll()
|
||||||
.and().authorizeRequests().antMatchers("/user/login/**").permitAll()
|
.and().authorizeRequests().antMatchers("/user/login/**").permitAll()
|
||||||
|
|||||||
@@ -2,6 +2,10 @@ package com.hideyoshi.backendportfolio.base.security.filter;
|
|||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.hideyoshi.backendportfolio.base.security.service.AuthService;
|
import com.hideyoshi.backendportfolio.base.security.service.AuthService;
|
||||||
|
import com.hideyoshi.backendportfolio.util.exception.AuthenticationInvalidException;
|
||||||
|
import com.hideyoshi.backendportfolio.util.exception.AuthenticationInvalidExceptionDetails;
|
||||||
|
import com.hideyoshi.backendportfolio.util.exception.BadRequestException;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
import org.springframework.web.filter.OncePerRequestFilter;
|
import org.springframework.web.filter.OncePerRequestFilter;
|
||||||
@@ -11,6 +15,7 @@ import javax.servlet.ServletException;
|
|||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import static org.springframework.http.HttpHeaders.AUTHORIZATION;
|
import static org.springframework.http.HttpHeaders.AUTHORIZATION;
|
||||||
@@ -20,9 +25,12 @@ import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
|
|||||||
public class CustomAuthorizationFilter extends OncePerRequestFilter {
|
public class CustomAuthorizationFilter extends OncePerRequestFilter {
|
||||||
|
|
||||||
private static final List<String> notProtectedPaths = Arrays.asList(
|
private static final List<String> notProtectedPaths = Arrays.asList(
|
||||||
|
"/health",
|
||||||
"/user/login",
|
"/user/login",
|
||||||
"/user/signup",
|
"/user/signup",
|
||||||
"/user/login/refresh"
|
"/user/login/refresh",
|
||||||
|
"/session/validate",
|
||||||
|
"/session/destroy"
|
||||||
);
|
);
|
||||||
|
|
||||||
private static final String AUTHORIZATION_TYPE_STRING = "Bearer ";
|
private static final String AUTHORIZATION_TYPE_STRING = "Bearer ";
|
||||||
@@ -38,37 +46,41 @@ public class CustomAuthorizationFilter extends OncePerRequestFilter {
|
|||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
if (this.isPathNotProtected(request.getServletPath())) {
|
if (this.isPathNotProtected(request.getServletPath())) {
|
||||||
filterChain.doFilter(request, response);
|
filterChain.doFilter(request, response);
|
||||||
} else {
|
return;
|
||||||
String authorizationHeader = request.getHeader(AUTHORIZATION);
|
}
|
||||||
if (Objects.nonNull(authorizationHeader) && authorizationHeader.startsWith(AUTHORIZATION_TYPE_STRING)) {
|
|
||||||
try {
|
|
||||||
|
|
||||||
|
String authorizationHeader = request.getHeader(AUTHORIZATION);
|
||||||
|
|
||||||
|
try {
|
||||||
UsernamePasswordAuthenticationToken authenticationToken =
|
UsernamePasswordAuthenticationToken authenticationToken =
|
||||||
this.authService.verifyAccessToken(authorizationHeader);
|
this.validateUserAccess(authorizationHeader);
|
||||||
|
|
||||||
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
|
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
|
||||||
filterChain.doFilter(request, response);
|
filterChain.doFilter(request, response);
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
response.setHeader("error", e.getMessage());
|
response.setHeader("error", e.getMessage());
|
||||||
|
|
||||||
response.setStatus(FORBIDDEN.value());
|
response.setStatus(FORBIDDEN.value());
|
||||||
|
|
||||||
Map<String, String> error = new HashMap<>();
|
AuthenticationInvalidExceptionDetails error = new AuthenticationInvalidExceptionDetails("Authentication Failed. Check your credentials.",
|
||||||
error.put("error_message", e.getMessage());
|
HttpStatus.FORBIDDEN.value(), e.getMessage(),
|
||||||
|
e.getClass().getName(), LocalDateTime.now());
|
||||||
|
|
||||||
response.setContentType(APPLICATION_JSON_VALUE);
|
response.setContentType(APPLICATION_JSON_VALUE);
|
||||||
new ObjectMapper()
|
new ObjectMapper()
|
||||||
.writeValue(response.getOutputStream(), error);
|
.writeValue(response.getOutputStream(), error);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
filterChain.doFilter(request, response);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Boolean isPathNotProtected(String path) {
|
private Boolean isPathNotProtected(String path) {
|
||||||
return notProtectedPaths.contains(path);
|
return notProtectedPaths.contains(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private UsernamePasswordAuthenticationToken validateUserAccess(String authorizationHeader) {
|
||||||
|
if (Objects.nonNull(authorizationHeader) && authorizationHeader.startsWith(AUTHORIZATION_TYPE_STRING)) {
|
||||||
|
return this.authService.verifyAccessToken(authorizationHeader);
|
||||||
|
} else {
|
||||||
|
throw new AuthenticationInvalidException("Access denied");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.hideyoshi.backendportfolio.base.security.interceptor;
|
|||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.hideyoshi.backendportfolio.base.user.service.UserService;
|
import com.hideyoshi.backendportfolio.base.user.service.UserService;
|
||||||
|
import com.hideyoshi.backendportfolio.util.exception.AuthenticationInvalidException;
|
||||||
import com.hideyoshi.backendportfolio.util.exception.BadRequestException;
|
import com.hideyoshi.backendportfolio.util.exception.BadRequestException;
|
||||||
import com.hideyoshi.backendportfolio.util.guard.UserResourceGuard;
|
import com.hideyoshi.backendportfolio.util.guard.UserResourceGuard;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
@@ -36,7 +37,7 @@ public class UserResourceAccessInterceptor implements HandlerInterceptor {
|
|||||||
Boolean accessPermission =
|
Boolean accessPermission =
|
||||||
annotation.accessType().hasAccess(this.userService, this.objectMapper, request);
|
annotation.accessType().hasAccess(this.userService, this.objectMapper, request);
|
||||||
if (!accessPermission) {
|
if (!accessPermission) {
|
||||||
throw new BadRequestException(annotation.denialMessage());
|
throw new AuthenticationInvalidException(annotation.denialMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
package com.hideyoshi.backendportfolio.healthChecker.api;
|
package com.hideyoshi.backendportfolio.healthChecker.api;
|
||||||
|
|
||||||
|
|
||||||
|
import com.hideyoshi.backendportfolio.util.guard.UserResourceGuard;
|
||||||
|
import com.hideyoshi.backendportfolio.util.guard.UserResourceGuardEnum;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.log4j.Log4j2;
|
import lombok.extern.log4j.Log4j2;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
@@ -11,9 +14,11 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
@Log4j2
|
@Log4j2
|
||||||
@Controller
|
@Controller
|
||||||
@RestController
|
@RestController
|
||||||
|
@RequiredArgsConstructor
|
||||||
@RequestMapping("/health")
|
@RequestMapping("/health")
|
||||||
public class HealthCheckerController {
|
public class HealthCheckerController {
|
||||||
@RequestMapping
|
@RequestMapping
|
||||||
|
@UserResourceGuard(accessType = UserResourceGuardEnum.OPEN)
|
||||||
public ResponseEntity<String> healthCheck() {
|
public ResponseEntity<String> healthCheck() {
|
||||||
log.info("Health check requested");
|
log.info("Health check requested");
|
||||||
return ResponseEntity.ok("Health check successful!");
|
return ResponseEntity.ok("Health check successful!");
|
||||||
|
|||||||
Reference in New Issue
Block a user