Ignore access token header if client has Athenz role certificate
@@ -111,10 +111,10 @@ public class AthenzAuthorizationFilter extends JsonSecurityRequestFilterBase {
// Note: the ordering of the if-constructs determines the precedence of the credential types
if (enabledCredentials.contains(ACCESS_TOKEN)
&& isAccessTokenPresent(request)
- && isClientCertificatePresent(request)) {
+ && isIdentityCertificatePresent(request)) {
return checkAccessWithAccessToken(request, resourceAndAction);
} else if (enabledCredentials.contains(ROLE_CERTIFICATE)
- && isClientCertificatePresent(request)) {
+ && isRoleCertificatePresent(request)) {
return checkAccessWithRoleCertificate(request, resourceAndAction);
} else if (enabledCredentials.contains(ROLE_TOKEN)
&& isRoleTokenPresent(request)) {
@@ -127,7 +127,7 @@ public class AthenzAuthorizationFilter extends JsonSecurityRequestFilterBase {
private Result checkAccessWithAccessToken(DiscFilterRequest request, ResourceNameAndAction resourceAndAction) {
AthenzAccessToken accessToken = getAccessToken(request);
- X509Certificate identityCertificate = getClientCertificate(request);
+ X509Certificate identityCertificate = getClientCertificate(request).get();
AthenzIdentity peerIdentity = AthenzIdentities.from(identityCertificate);
if (allowedProxyIdentities.contains(peerIdentity)) {
return checkAccessWithProxiedAccessToken(resourceAndAction, accessToken, identityCertificate);
@@ -147,7 +147,7 @@ public class AthenzAuthorizationFilter extends JsonSecurityRequestFilterBase {
}
private Result checkAccessWithRoleCertificate(DiscFilterRequest request, ResourceNameAndAction resourceAndAction) {
- X509Certificate roleCertificate = getClientCertificate(request);
+ X509Certificate roleCertificate = getClientCertificate(request).get();
var zpeResult = zpe.checkAccessAllowed(roleCertificate, resourceAndAction.resourceName(), resourceAndAction.action());
AthenzIdentity identity = AthenzX509CertificateUtils.getIdentityFromRoleCertificate(roleCertificate);
return new Result(ROLE_CERTIFICATE, identity, zpeResult);
@@ -163,8 +163,34 @@ public class AthenzAuthorizationFilter extends JsonSecurityRequestFilterBase {
return request.getHeader(AthenzAccessToken.HTTP_HEADER_NAME) != null;
}
- private static boolean isClientCertificatePresent(DiscFilterRequest request) {
- return !request.getClientCertificateChain().isEmpty();
+ // Check that client certificate looks like a role certificate
+ private static boolean isRoleCertificatePresent(DiscFilterRequest request) {
+ return getClientCertificate(request)
+ .filter(cert -> {
+ try {
+ AthenzX509CertificateUtils.getRolesFromRoleCertificate(cert);
+ return true;
+ } catch (Exception e) {
+ log.log(Level.FINE, e, () -> "Not a role certificate: " + e.getMessage());
+ return false;
+ }
+ })
+ .isPresent();
+ }
+
+ // Check that client certificate looks like an identity certificate
+ private static boolean isIdentityCertificatePresent(DiscFilterRequest request) {
+ return getClientCertificate(request)
+ .filter(cert -> {
+ try {
+ AthenzIdentities.from(cert);
+ return true;
+ } catch (Exception e) {
+ log.log(Level.FINE, e, () -> "Not an identity certificate: " + e.getMessage());
+ return false;
+ }
+ })
+ .isPresent();
}
private boolean isRoleTokenPresent(DiscFilterRequest request) {
@@ -175,8 +201,10 @@ public class AthenzAuthorizationFilter extends JsonSecurityRequestFilterBase {
return new AthenzAccessToken(request.getHeader(AthenzAccessToken.HTTP_HEADER_NAME));
}
- private static X509Certificate getClientCertificate(DiscFilterRequest request) {
- return request.getClientCertificateChain().get(0);
+ private static Optional<X509Certificate> getClientCertificate(DiscFilterRequest request) {
+ List<X509Certificate> certificates = request.getClientCertificateChain();
+ if (certificates.isEmpty()) return Optional.empty();
+ return Optional.of(certificates.get(0));
}
private ZToken getRoleToken(DiscFilterRequest request) {
