Skip to content

Commit

Permalink
PR remarks
Browse files Browse the repository at this point in the history
  • Loading branch information
ndr-brt committed Sep 26, 2022
1 parent 97c673a commit 36b5683
Show file tree
Hide file tree
Showing 9 changed files with 79 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -53,18 +53,16 @@ public Result<Void> checkRule(@NotNull ClaimToken toVerify, @Nullable Map<String
}

private Result<Void> verifyTokenIds(ClaimToken jwt, String issuerConnector, @Nullable String securityProfile) {
var claims = jwt.getClaims();

//referringConnector (DAT, optional) vs issuerConnector (Message-Header, mandatory)
var referringConnector = claims.get("referringConnector");
var referringConnector = jwt.getClaim("referringConnector");

if (validateReferring && !issuerConnector.equals(referringConnector)) {
return Result.failure("refferingConnector in token does not match issuerConnector in message");
}

//securityProfile (DAT, mandatory) vs securityProfile (Message-Payload, optional)
try {
var tokenSecurityProfile = claims.get("securityProfile");
var tokenSecurityProfile = jwt.getClaim("securityProfile");

if (securityProfile != null && !securityProfile.equals(tokenSecurityProfile)) {
return Result.failure("securityProfile in token does not match securityProfile in payload");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ void generateAndVerifyJwtToken_valid() {

Result<ClaimToken> verificationResult = identityService.verifyJwtToken(result.getContent(), "Bar");
assertTrue(verificationResult.succeeded());
assertEquals("eu", verificationResult.getContent().getClaims().get("region"));
assertEquals("eu", verificationResult.getContent().getStringClaim("region"));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import static org.eclipse.dataspaceconnector.spi.jwt.JwtRegisteredClaimNames.AUDIENCE;

/**
* Token validation rule that checks if the "audience" of token contains the expected audience
*/
public class Oauth2AudienceValidationRule implements TokenValidationRule {

private final String endpointAudience;
Expand All @@ -38,9 +38,7 @@ public Oauth2AudienceValidationRule(String endpointAudience) {

@Override
public Result<Void> checkRule(@NotNull ClaimToken toVerify, @Nullable Map<String, Object> additional) {
var claims = toVerify.getClaims();

var audiences = Optional.of(claims).map(it -> it.get(AUDIENCE)).map(List.class::cast).orElse(Collections.emptyList());
var audiences = toVerify.getListClaim(AUDIENCE);
if (audiences.isEmpty()) {
return Result.failure("Required audience (aud) claim is missing in token");
} else if (!audiences.contains(endpointAudience)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,14 @@
import org.jetbrains.annotations.Nullable;

import java.time.Clock;
import java.time.Instant;
import java.time.ZonedDateTime;
import java.util.Date;
import java.util.Map;

import static java.time.ZoneOffset.UTC;
import static org.eclipse.dataspaceconnector.spi.jwt.JwtRegisteredClaimNames.EXPIRATION_TIME;
import static org.eclipse.dataspaceconnector.spi.jwt.JwtRegisteredClaimNames.ISSUED_AT;

/**
* Token validation rule that checks if the token is not expired and if the "issued at" claim is valued correctly
*/
public class Oauth2ExpirationIssuedAtValidationRule implements TokenValidationRule {

private final Clock clock;
Expand All @@ -42,27 +41,23 @@ public Oauth2ExpirationIssuedAtValidationRule(Clock clock) {
@Override
public Result<Void> checkRule(@NotNull ClaimToken toVerify, @Nullable Map<String, Object> additional) {
var now = clock.instant();
var claims = toVerify.getClaims();
var expires = (Date) claims.get(EXPIRATION_TIME);
var expires = toVerify.getInstantClaim(EXPIRATION_TIME);
if (expires == null) {
return Result.failure("Required expiration time (exp) claim is missing in token");
} else if (now.isAfter(convertToUtcTime(expires))) {
} else if (now.isAfter(expires)) {
return Result.failure("Token has expired (exp)");
}

var issuedAt = (Date) claims.get(ISSUED_AT);
var issuedAt = toVerify.getInstantClaim(ISSUED_AT);
if (issuedAt != null) {
if (issuedAt.toInstant().isAfter(expires.toInstant())) {
if (issuedAt.isAfter(expires)) {
return Result.failure("Issued at (iat) claim is after expiration time (exp) claim in token");
} else if (now.isBefore(convertToUtcTime(issuedAt))) {
} else if (now.isBefore(issuedAt)) {
return Result.failure("Current date/time before issued at (iat) claim in token");
}
}

return Result.success();
}

private static Instant convertToUtcTime(Date date) {
return ZonedDateTime.ofInstant(date.toInstant(), UTC).toInstant();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,13 @@
import org.jetbrains.annotations.Nullable;

import java.time.Clock;
import java.time.Instant;
import java.time.ZonedDateTime;
import java.util.Date;
import java.util.Map;

import static java.time.ZoneOffset.UTC;
import static org.eclipse.dataspaceconnector.spi.jwt.JwtRegisteredClaimNames.NOT_BEFORE;

/**
* Token validation rule that checks if the "not before" claim is valid
*/
public class Oauth2NotBeforeValidationRule implements TokenValidationRule {
private final Clock clock;
private final int notBeforeLeeway;
Expand All @@ -43,19 +42,14 @@ public Oauth2NotBeforeValidationRule(Clock clock, int notBeforeLeeway) {
public Result<Void> checkRule(@NotNull ClaimToken toVerify, @Nullable Map<String, Object> additional) {
var now = clock.instant();
var leewayNow = now.plusSeconds(notBeforeLeeway);
var claims = toVerify.getClaims();
var notBefore = (Date) claims.get(NOT_BEFORE);
var notBefore = toVerify.getInstantClaim(NOT_BEFORE);

if (notBefore == null) {
return Result.failure("Required not before (nbf) claim is missing in token");
} else if (leewayNow.isBefore(convertToUtcTime(notBefore))) {
} else if (leewayNow.isBefore(notBefore)) {
return Result.failure("Current date/time with leeway before the not before (nbf) claim in token");
}

return Result.success();
}

private static Instant convertToUtcTime(Date date) {
return ZonedDateTime.ofInstant(date.toInstant(), UTC).toInstant();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public DataAddress validate(@HeaderParam(HttpHeaders.AUTHORIZATION) String token
throw new NotAuthorizedException("Token validation failed: " + join(", ", result.getFailureMessages()));
}

var obj = result.getContent().getClaims().get(DATA_ADDRESS);
var obj = result.getContent().getClaim(DATA_ADDRESS);
if (!(obj instanceof String)) {
throw new IllegalArgumentException(format("Missing claim `%s` in token", DATA_ADDRESS));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public ContractValidationRule(ContractNegotiationStore contractNegotiationStore,

@Override
public Result<Void> checkRule(@NotNull ClaimToken toVerify, @Nullable Map<String, Object> additional) {
String contractId = (String) toVerify.getClaims().get(CONTRACT_ID);
var contractId = toVerify.getStringClaim(CONTRACT_ID);

if (contractId == null) {
return Result.failure(String.format("Missing contract id claim `%s`", CONTRACT_ID));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import org.jetbrains.annotations.Nullable;

import java.time.Clock;
import java.util.Date;
import java.util.Map;

import static org.eclipse.dataspaceconnector.spi.jwt.JwtRegisteredClaimNames.EXPIRATION_TIME;
Expand All @@ -39,13 +38,13 @@ public ExpirationDateValidationRule(Clock clock) {

@Override
public Result<Void> checkRule(@NotNull ClaimToken toVerify, @Nullable Map<String, Object> additional) {
var expiration = (Date) toVerify.getClaims().get(EXPIRATION_TIME);
var expiration = toVerify.getInstantClaim(EXPIRATION_TIME);
if (expiration == null) {
return Result.failure("Missing expiration time in token");
}

// check contract expiration date
if (clock.instant().isAfter(expiration.toInstant())) {
if (clock.instant().isAfter(expiration)) {
return Result.failure("Token has expired on " + expiration);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,15 @@

package org.eclipse.dataspaceconnector.spi.iam;

import java.time.Instant;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import static java.time.ZoneOffset.UTC;

/**
* Models a token containing claims such as a JWT.
Expand All @@ -33,6 +40,54 @@ public Map<String, Object> getClaims() {
return claims;
}

/**
* Get the claim value by name
*
* @param claimName the name of the claim
* @return the claim value, null if it does not exist
*/
public Object getClaim(String claimName) {
return claims.get(claimName);
}

/**
* Get the date claim value by name cast to {@link String}
*
* @param claimName the name of the claim
* @return the claim value, null if it does not exist
*/
public String getStringClaim(String claimName) {
return Optional.of(claims).map(it -> it.get(claimName)).map(String.class::cast).orElse(null);
}

/**
* Get the date claim value by name cast to {@link List}
*
* @param claimName the name of the claim
* @return the claim value, null if it does not exist
*/
public List<?> getListClaim(String claimName) {
return Optional.of(claims).map(it -> it.get(claimName)).map(List.class::cast).orElse(Collections.emptyList());
}

/**
* Get the date claim value by name converted to {@link Instant}
*
* @param claimName the name of the claim
* @return the claim value, null if it does not exist
*/
public Instant getInstantClaim(String claimName) {
return Optional.of(claims)
.map(it -> it.get(claimName))
.map(Date.class::cast)
.map(this::convertToUtcTime)
.orElse(null);
}

private Instant convertToUtcTime(Date date) {
return date.toInstant().atOffset(UTC).toInstant();
}

public static class Builder {
private final ClaimToken token;

Expand Down

0 comments on commit 36b5683

Please sign in to comment.