Skip to content

Commit

Permalink
Task 38 : Revise filters and config file with adding logs
Browse files Browse the repository at this point in the history
  • Loading branch information
Rapter1990 committed Jul 18, 2024
1 parent 02d508b commit 61bc9b2
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,13 @@ public GatewayFilter apply(Config config) {

return Mono.fromCallable(() -> {
userServiceClient.validateToken(jwt);
log.debug("Token validation succeeded for path: {}", path);
return true;
})
.subscribeOn(Schedulers.boundedElastic())
.flatMap(valid -> chain.filter(exchange))
.onErrorResume(e -> {
log.error("Token validation failed for path: {}", path, e);
if (e instanceof FeignException.Unauthorized || e instanceof FeignException.Forbidden) {
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
} else {
Expand All @@ -68,7 +70,7 @@ public GatewayFilter apply(Config config) {
return exchange.getResponse().setComplete();
});
}

log.warn("Missing or invalid Authorization header for path: {}", path);
return chain.filter(exchange);
};
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package com.springbootmicroservices.productservice.config;

import com.springbootmicroservices.productservice.client.UserServiceClient;
import com.springbootmicroservices.productservice.filter.CustomBearerTokenAuthenticationFilter;
import com.springbootmicroservices.productservice.security.CustomAuthenticationEntryPoint;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
Expand All @@ -28,10 +28,9 @@
@EnableWebSecurity
@RequiredArgsConstructor
@EnableMethodSecurity
@Slf4j
public class SecurityConfig {

private final UserServiceClient userServiceClient;

@Bean
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
Expand All @@ -44,6 +43,8 @@ public SecurityFilterChain filterChain(
final CustomAuthenticationEntryPoint customAuthenticationEntryPoint
) throws Exception {

log.debug("Configuring Security Filter Chain");

httpSecurity
.exceptionHandling(customizer -> customizer.authenticationEntryPoint(customAuthenticationEntryPoint))
.cors(customizer -> customizer.configurationSource(corsConfigurationSource()))
Expand All @@ -54,6 +55,8 @@ public SecurityFilterChain filterChain(
.sessionManagement(customizer -> customizer.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.addFilterBefore(customBearerTokenAuthenticationFilter, BearerTokenAuthenticationFilter.class);

log.debug("CustomBearerTokenAuthenticationFilter added to the filter chain");

return httpSecurity.build();
}

Expand All @@ -71,5 +74,5 @@ private CorsConfigurationSource corsConfigurationSource() {
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.springbootmicroservices.productservice.client.UserServiceClient;
import com.springbootmicroservices.productservice.model.auth.Token;
import feign.FeignException;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
Expand All @@ -10,8 +11,11 @@
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Schedulers;

import java.io.IOException;

Expand All @@ -27,15 +31,46 @@ protected void doFilterInternal(@NonNull final HttpServletRequest httpServletReq
@NonNull final HttpServletResponse httpServletResponse,
@NonNull final FilterChain filterChain) throws ServletException, IOException {

log.debug("API Request was secured with Security!");
log.debug("CustomBearerTokenAuthenticationFilter: Request received for URI: {}", httpServletRequest.getRequestURI());

final String authorizationHeader = httpServletRequest.getHeader(HttpHeaders.AUTHORIZATION);

if (Token.isBearerToken(authorizationHeader)) {
final String jwt = Token.getJwt(authorizationHeader);
userServiceClient.validateToken(jwt);
}

filterChain.doFilter(httpServletRequest, httpServletResponse);
// Use Mono.fromCallable for async processing
Mono.fromCallable(() -> {
userServiceClient.validateToken(jwt);
log.debug("Token validation succeeded for request: {}", httpServletRequest.getRequestURI());
return true;
})
.subscribeOn(Schedulers.boundedElastic())
.flatMap(valid -> {
try {
filterChain.doFilter(httpServletRequest, httpServletResponse);
} catch (IOException | ServletException e) {
throw new RuntimeException(e);
}
return Mono.empty();
})
.onErrorResume(e -> {
log.error("Token validation failed for request: {}", httpServletRequest.getRequestURI(), e);
try {
if (e instanceof FeignException.Unauthorized || e instanceof FeignException.Forbidden) {
httpServletResponse.setStatus(HttpStatus.UNAUTHORIZED.value());
} else {
httpServletResponse.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
}
httpServletResponse.getWriter().write(e.getMessage());
} catch (IOException ex) {
log.error("Error writing response", ex);
}
return Mono.empty();
})
.block();
} else {
log.warn("Missing or invalid Authorization header for request: {}", httpServletRequest.getRequestURI());
filterChain.doFilter(httpServletRequest, httpServletResponse);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,22 @@
import com.springbootmicroservices.userservice.model.user.enums.UserType;
import com.springbootmicroservices.userservice.service.InvalidTokenService;
import com.springbootmicroservices.userservice.service.TokenService;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.JwsHeader;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.stereotype.Service;
import org.springframework.web.server.ResponseStatusException;

import java.util.*;

@Service
@RequiredArgsConstructor
@Slf4j
public class TokenServiceImpl implements TokenService {

private final TokenConfigurationParameter tokenConfigurationParameter;
Expand Down Expand Up @@ -141,10 +142,31 @@ public UsernamePasswordAuthenticationToken getAuthentication(final String token)
}

public void verifyAndValidate(final String jwt) {
Jwts.parser()

try {
Jws<Claims> claimsJws = Jwts.parser()
.verifyWith(tokenConfigurationParameter.getPublicKey())
.build()
.parseSignedClaims(jwt);

// Log the claims for debugging purposes
Claims claims = claimsJws.getBody();
log.info("Token claims: {}", claims);

// Additional checks (e.g., expiration, issuer, etc.)
if (claims.getExpiration().before(new Date())) {
throw new JwtException("Token has expired");
}

log.info("Token is valid");

} catch (JwtException e) {
log.error("Invalid JWT token", e);
throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, "Invalid JWT token", e);
} catch (Exception e) {
log.error("Error validating token", e);
throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "Error validating token", e);
}
}

@Override
Expand Down

0 comments on commit 61bc9b2

Please sign in to comment.