ApiKeyAuthenticationFilter.java
Bridget/payment_solutions/src/main/java/com/checkout/payment/gateway/security/ApiKeyAuthenticationFilter.java
package com.checkout.payment.gateway.security;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;
@Component
public class ApiKeyAuthenticationFilter extends OncePerRequestFilter {
public static final String API_KEY_HEADER = "X-API-Key";
private final boolean securityEnabled;
private final List<String> merchantKeys;
private final List<String> adminKeys;
public ApiKeyAuthenticationFilter(
@Value("${gateway.security.enabled:true}") boolean securityEnabled,
@Value("${gateway.security.merchant-api-keys:}") String merchantApiKeys,
@Value("${gateway.security.admin-api-keys:}") String adminApiKeys) {
this.securityEnabled = securityEnabled;
this.merchantKeys = splitKeys(merchantApiKeys);
this.adminKeys = splitKeys(adminApiKeys);
}
private static List<String> splitKeys(String raw) {
List<String> keys = new ArrayList<>();
if (!StringUtils.hasText(raw)) {
return keys;
}
for (String part : raw.split(",")) {
String trimmed = part.trim();
if (StringUtils.hasText(trimmed)) {
keys.add(trimmed);
}
}
return keys;
}
@Override
protected boolean shouldNotFilter(HttpServletRequest request) {
if (!securityEnabled) {
return true;
}
String path = request.getRequestURI();
return path.startsWith("/actuator/health")
|| path.equals("/actuator/health/")
|| path.startsWith("/swagger-ui")
|| path.startsWith("/v3/api-docs");
}
@Override
protected void doFilterInternal(
HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
String apiKey = request.getHeader(API_KEY_HEADER);
if (!StringUtils.hasText(apiKey)) {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Missing " + API_KEY_HEADER);
return;
}
apiKey = apiKey.trim();
Collection<GrantedAuthority> authorities = new ArrayList<>();
if (adminKeys.contains(apiKey)) {
authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
authorities.add(new SimpleGrantedAuthority("ROLE_MERCHANT"));
} else if (merchantKeys.contains(apiKey)) {
authorities.add(new SimpleGrantedAuthority("ROLE_MERCHANT"));
} else {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid API key");
return;
}
Authentication authentication = new ApiKeyAuthentication(apiKey, authorities);
SecurityContextHolder.getContext().setAuthentication(authentication);
filterChain.doFilter(request, response);
}
private static final class ApiKeyAuthentication extends AbstractAuthenticationToken {
private final String apiKey;
private ApiKeyAuthentication(String apiKey, Collection<GrantedAuthority> authorities) {
super(authorities);
this.apiKey = apiKey;
setAuthenticated(true);
}
@Override
public Object getCredentials() {
return "";
}
@Override
public Object getPrincipal() {
return apiKey;
}
}
}
Articles liés
PaymentGatewayApplication.java
PaymentGatewayApplication.java — java source code from the Bridget learning materials (Bridget/payment-gateway-challenge-java/src/main/java/com/checkout/payment/gateway/PaymentGatewayApplication.java).
Lire l'article →ApplicationConfiguration.java
ApplicationConfiguration.java — java source code from the Bridget learning materials (Bridget/payment-gateway-challenge-java/src/main/java/com/checkout/payment/gateway/configuration/ApplicationConfiguration.java).
Lire l'article →RequestResponseLogger.java
RequestResponseLogger.java — java source code from the Bridget learning materials (Bridget/payment-gateway-challenge-java/src/main/java/com/checkout/payment/gateway/configuration/RequestResponseLogger.java).
Lire l'article →PaymentGatewayController.java
PaymentGatewayController.java — java source code from the Bridget learning materials (Bridget/payment-gateway-challenge-java/src/main/java/com/checkout/payment/gateway/controller/PaymentGatewayController.java).
Lire l'article →PaymentStatus.java
PaymentStatus.java — java source code from the Bridget learning materials (Bridget/payment-gateway-challenge-java/src/main/java/com/checkout/payment/gateway/enums/PaymentStatus.java).
Lire l'article →BankErrorException.java
BankErrorException.java — java source code from the Bridget learning materials (Bridget/payment-gateway-challenge-java/src/main/java/com/checkout/payment/gateway/exception/BankErrorException.java).
Lire l'article →