Untitled
unknown
java
2 years ago
5.0 kB
26
Indexable
package com.decode.msapp.apigw.config;
import com.decode.msapp.apigw.exceptions.AuthHeaderMissingException;
import com.decode.msapp.apigw.exceptions.CantValidateTokenException;
import com.decode.msapp.apigw.service.JwtService;
import io.jsonwebtoken.ExpiredJwtException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.io.IOException;
import java.net.URI;
@Component
@Slf4j
/* Filters inbound requests for auth Token, might consider to use GlobalFilter
for requests to ALL microservices */
public class AuthFilter extends AbstractGatewayFilterFactory<AuthFilter.Config> {
private final RouteValidator routeValidator;
private final WebClient webClient;
private final JwtService jwtService;
private static String AUTH_ERROR_PAGE_URL;
public AuthFilter(RouteValidator routeValidator, WebClient.Builder webClientBuilder, JwtService jwtService) {
super(Config.class);
this.routeValidator=routeValidator;
this.webClient=webClientBuilder.build();
this.jwtService=jwtService;
}
@Override
public GatewayFilter apply(Config config) {
return ((exchange, chain) -> {
ServerHttpRequest request = null;
if (routeValidator.isSecured.test(exchange.getRequest())) {
if (!exchange.getRequest().getHeaders().containsKey(HttpHeaders.AUTHORIZATION)) {
log.error("No authorization Token was provided in the request's header");
return chain.filter(getModifiedExchange(exchange));
}
String authHeader = exchange.getRequest().getHeaders().get(HttpHeaders.AUTHORIZATION).get(0);
if (authHeader!=null && authHeader.startsWith("Bearer ")) {
authHeader = authHeader.substring(7);
var authHeaderSearch = authHeader;
Mono<String> result;
try {
result = webClient.get()
.uri(uriBuilder -> uriBuilder.path("/users/validate")
.queryParam("token", authHeaderSearch)
.build())
.retrieve()
.bodyToMono(String.class)
.onErrorResume(Exception.class, throwable -> Mono.error(new CantValidateTokenException("")))
;
result
.onErrorResume(Exception.class, throwable -> Mono.error(new CantValidateTokenException("")))
.subscribe(e -> log.info("Tocken check result is: " + e))
;
/* Adding User information to request payload */
var userNameJWT=jwtService.extractUsername(authHeader);
var userRoleJWT=jwtService.extractUserRole(authHeader);
request = exchange.getRequest()
.mutate()
.header("loggedInUser", userNameJWT)
.header("loggedInRole", userRoleJWT)
.build();
} catch (Exception e) {
log.error("The Token was invalid or can't be checked. Exception: {}, Message: {} ", e.getClass(), e.getMessage());
return chain.filter(getModifiedExchange(exchange));
}
}
}
return chain.filter(exchange.mutate().request(request).build());
});
}
/* Redirects to auth error page if there was no Token, or it's invalid */
private static ServerWebExchange getModifiedExchange(ServerWebExchange exchange) {
log.info("No token was found, redirecting to auth page: {}", AUTH_ERROR_PAGE_URL);
ServerHttpRequest modifiedRequest = exchange.getRequest()
.mutate()
.uri(URI.create(AUTH_ERROR_PAGE_URL))
.build();
return exchange.mutate().request(modifiedRequest).build();
}
public static class Config {
}
//Setter for static URL
@Value("${app.authfailurl}")
public void setURLStatic(String url){
AuthFilter.AUTH_ERROR_PAGE_URL = url;
}
}
Editor is loading...