Skip to content

Commit

Permalink
Add one more OIDC tenant-paths resolution test
Browse files Browse the repository at this point in the history
  • Loading branch information
sberyozkin committed May 29, 2024
1 parent ecdf3ea commit 9ae780f
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package io.quarkus.it.keycloak;

import jakarta.annotation.security.RolesAllowed;
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;

import io.quarkus.security.identity.SecurityIdentity;

@Path("/upload")
public class UploadResource {

@Inject
SecurityIdentity identity;

@GET
@RolesAllowed("admin")
@Produces(MediaType.APPLICATION_JSON)
public String bearerCertificateCustomValidator() {
return "granted:" + identity.getRoles();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package io.quarkus.it.keycloak;

import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.List;

import jakarta.enterprise.context.ApplicationScoped;

import io.quarkus.arc.Unremovable;
import io.quarkus.oidc.OidcTenantConfig;
import io.quarkus.oidc.TenantFeature;
import io.quarkus.oidc.TokenCertificateValidator;
import io.quarkus.oidc.runtime.TrustStoreUtils;
import io.vertx.core.json.JsonObject;

@ApplicationScoped
@Unremovable
@TenantFeature("uploads")
public class UploadsTokenChainValidator implements TokenCertificateValidator {

@Override
public void validate(OidcTenantConfig oidcConfig, List<X509Certificate> chain, String tokenClaims)
throws CertificateException {
if (!"uploads".equals(oidcConfig.tenantId.get())) {
throw new RuntimeException("Unexpected tenant id");
}
String leafCertificateThumbprint = TrustStoreUtils.calculateThumprint(chain.get(0));
JsonObject claims = new JsonObject(tokenClaims);
if (!leafCertificateThumbprint.equals(claims.getString("leaf-certificate-thumbprint"))) {
throw new CertificateException("Invalid leaf certificate");
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,10 @@ quarkus.oidc.bearer-certificate-full-chain.certificate-chain.trust-store-passwor
quarkus.oidc.bearer-chain-custom-validator.certificate-chain.trust-store-file=truststore.p12
quarkus.oidc.bearer-chain-custom-validator.certificate-chain.trust-store-password=storepassword

quarkus.oidc.uploads.tenant-paths=/upload/*
quarkus.oidc.uploads.certificate-chain.trust-store-file=truststore.p12
quarkus.oidc.uploads.certificate-chain.trust-store-password=storepassword

quarkus.oidc.bearer-certificate-full-chain-root-only-wrongcname.certificate-chain.trust-store-file=truststore-rootcert.p12
quarkus.oidc.bearer-certificate-full-chain-root-only-wrongcname.certificate-chain.trust-store-password=storepassword
quarkus.oidc.bearer-certificate-full-chain-root-only-wrongcname.certificate-chain.leaf-certificate-name=www.quarkusio.com
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,36 @@ public void testCertChainWithCustomValidator() throws Exception {

}

@Test
public void testCertChainWithCustomValidatorUpload() throws Exception {
X509Certificate rootCert = KeyUtils.getCertificate(ResourceUtils.readResource("/ca.cert.pem"));
X509Certificate intermediateCert = KeyUtils.getCertificate(ResourceUtils.readResource("/intermediate.cert.pem"));
X509Certificate subjectCert = KeyUtils.getCertificate(ResourceUtils.readResource("/www.quarkustest.com.cert.pem"));
PrivateKey subjectPrivateKey = KeyUtils.readPrivateKey("/www.quarkustest.com.key.pem");

// Send the token with the valid certificate chain and bind it to the token claim
String accessToken = getAccessTokenForCustomValidator(
List.of(subjectCert, intermediateCert, rootCert),
subjectPrivateKey, true);

RestAssured.given().auth().oauth2(accessToken)
.when().get("/upload")
.then()
.statusCode(200)
.body(Matchers.containsString("admin"));

// Send the token with the valid certificate chain but do bind it to the token claim
accessToken = getAccessTokenForCustomValidator(
List.of(subjectCert, intermediateCert, rootCert),
subjectPrivateKey, false);

RestAssured.given().auth().oauth2(accessToken)
.when().get("/upload")
.then()
.statusCode(401);

}

@Test
public void testAccessAdminResourceWithFullCertChain() throws Exception {
X509Certificate rootCert = KeyUtils.getCertificate(ResourceUtils.readResource("/ca.cert.pem"));
Expand Down

0 comments on commit 9ae780f

Please sign in to comment.