Search in sources :

Example 1 with ExtractResult

use of org.dcache.gplazma.oidc.ExtractResult in project dcache by dCache.

the class QueryUserInfoEndpoint method extract.

@Override
public ExtractResult extract(String token) throws AuthenticationException {
    Stopwatch userinfoLookupTiming = Stopwatch.createStarted();
    List<LookupResult> allResults;
    try {
        allResults = userInfoCache.get(token);
    } catch (ExecutionException e) {
        Throwable cause = e.getCause();
        Throwables.throwIfInstanceOf(cause, AuthenticationException.class);
        Throwables.throwIfUnchecked(cause);
        if (cause instanceof InterruptedException) {
            throw new AuthenticationException("Shutting down");
        }
        throw new RuntimeException("Unexpected exception", e);
    }
    if (LOG.isDebugEnabled()) {
        LOG.debug("Doing user-info lookup against {} OPs took {}", allResults.size(), TimeUtils.describe(userinfoLookupTiming.elapsed()).orElse("no time"));
    }
    List<LookupResult> successfulResults = allResults.stream().filter(LookupResult::isSuccess).collect(Collectors.toList());
    if (successfulResults.isEmpty()) {
        if (allResults.size() == 1) {
            LookupResult result = allResults.get(0);
            throw new AuthenticationException("OpenId Validation failed for " + result.getIdentityProvider().getName() + ": " + result.getError());
        } else {
            String randomId = randomId();
            String errors = allResults.stream().map(r -> "[" + r.getIdentityProvider().getName() + ": " + r.getError() + "]").collect(Collectors.joining(", "));
            LOG.warn("OpenId Validation Failure ({}): {}", randomId, errors);
            throw new AuthenticationException("OpenId Validation Failed check [log entry #" + randomId + "]");
        }
    }
    if (successfulResults.size() > 1) {
        String names = successfulResults.stream().map(LookupResult::getIdentityProvider).map(IdentityProvider::getName).collect(Collectors.joining(", "));
        LOG.warn("Multiple OpenID-Connect endpoints accepted access token: {}", names);
        throw new AuthenticationException("Multiple OPs accepted token.");
    }
    var result = successfulResults.get(0);
    return new ExtractResult(result.getIdentityProvider(), result.getClaims());
}
Also used : LoadingCache(com.google.common.cache.LoadingCache) ListenableFuture(com.google.common.util.concurrent.ListenableFuture) Stopwatch(com.google.common.base.Stopwatch) URISyntaxException(java.net.URISyntaxException) LoggerFactory(org.slf4j.LoggerFactory) ArrayList(java.util.ArrayList) ExtractResult(org.dcache.gplazma.oidc.ExtractResult) ListenableFutureTask(com.google.common.util.concurrent.ListenableFutureTask) Collectors.toMap(java.util.stream.Collectors.toMap) Duration(java.time.Duration) Map(java.util.Map) ThreadLocalRandom(java.util.concurrent.ThreadLocalRandom) Objects.requireNonNull(java.util.Objects.requireNonNull) JsonNode(com.fasterxml.jackson.databind.JsonNode) URI(java.net.URI) TimeUtils(org.dcache.util.TimeUtils) JsonHttpClient(org.dcache.gplazma.oidc.helpers.JsonHttpClient) ExecutorService(java.util.concurrent.ExecutorService) JsonNodeType(com.fasterxml.jackson.databind.node.JsonNodeType) Properties(java.util.Properties) Logger(org.slf4j.Logger) Preconditions.checkAuthentication(org.dcache.gplazma.util.Preconditions.checkAuthentication) PropertiesUtils.asInt(org.dcache.gplazma.oidc.PropertiesUtils.asInt) TokenProcessor(org.dcache.gplazma.oidc.TokenProcessor) Collection(java.util.Collection) JsonWebToken(org.dcache.gplazma.util.JsonWebToken) Throwables(com.google.common.base.Throwables) Set(java.util.Set) IOException(java.io.IOException) Streams(com.google.common.collect.Streams) Collectors(java.util.stream.Collectors) AuthenticationException(org.dcache.gplazma.AuthenticationException) CacheLoader(com.google.common.cache.CacheLoader) ExecutionException(java.util.concurrent.ExecutionException) TimeUnit(java.util.concurrent.TimeUnit) Futures(com.google.common.util.concurrent.Futures) Base64(java.util.Base64) List(java.util.List) ChronoUnit(java.time.temporal.ChronoUnit) Entry(java.util.Map.Entry) Optional(java.util.Optional) CacheBuilder(com.google.common.cache.CacheBuilder) Collections(java.util.Collections) IdentityProvider(org.dcache.gplazma.oidc.IdentityProvider) BoundedCachedExecutor(org.dcache.util.BoundedCachedExecutor) AuthenticationException(org.dcache.gplazma.AuthenticationException) Stopwatch(com.google.common.base.Stopwatch) ExecutionException(java.util.concurrent.ExecutionException) ExtractResult(org.dcache.gplazma.oidc.ExtractResult)

Example 2 with ExtractResult

use of org.dcache.gplazma.oidc.ExtractResult in project dcache by dCache.

the class OfflineJwtVerificationTest method shouldAcceptNonExpiredUnembargoedTokenFromTrustedOp.

@Test
public void shouldAcceptNonExpiredUnembargoedTokenFromTrustedOp() throws Exception {
    given(anIp("EXAMPLE").withEndpoint("https://oidc.example.org/"));
    given(anOfflineJwtVerification().withEmptyAudienceTargetProperty().withIssuer(anIssuer().withIp(identityProvider)));
    given(aJwt().withPayloadClaim("iss", "https://oidc.example.org/").withPayloadClaim("nbf", Instant.now().minus(5, MINUTES)).withPayloadClaim("exp", Instant.now().plus(5, MINUTES)).withPayloadClaim("sub", "paul"));
    ExtractResult result = verification.extract(jwt);
    assertThat(result.idp(), is(sameInstance(identityProvider)));
    assertThat(result.claims(), hasEntry("iss", jsonString("https://oidc.example.org/")));
    assertThat(result.claims(), hasEntry("sub", jsonString("paul")));
    assertThat(result.claims(), hasKey("nbf"));
    assertThat(result.claims(), hasKey("exp"));
}
Also used : ExtractResult(org.dcache.gplazma.oidc.ExtractResult) Test(org.junit.Test)

Example 3 with ExtractResult

use of org.dcache.gplazma.oidc.ExtractResult in project dcache by dCache.

the class OfflineJwtVerificationTest method shouldAcceptUnembargoedTokenFromTrustedOp.

@Test
public void shouldAcceptUnembargoedTokenFromTrustedOp() throws Exception {
    given(anIp("EXAMPLE").withEndpoint("https://oidc.example.org/"));
    given(anOfflineJwtVerification().withEmptyAudienceTargetProperty().withIssuer(anIssuer().withIp(identityProvider)));
    given(aJwt().withPayloadClaim("iss", "https://oidc.example.org/").withPayloadClaim("nbf", Instant.now().minus(5, MINUTES)).withPayloadClaim("sub", "paul"));
    ExtractResult result = verification.extract(jwt);
    assertThat(result.idp(), is(sameInstance(identityProvider)));
    assertThat(result.claims(), hasEntry("iss", jsonString("https://oidc.example.org/")));
    assertThat(result.claims(), hasEntry("sub", jsonString("paul")));
    assertThat(result.claims(), hasKey("nbf"));
}
Also used : ExtractResult(org.dcache.gplazma.oidc.ExtractResult) Test(org.junit.Test)

Example 4 with ExtractResult

use of org.dcache.gplazma.oidc.ExtractResult in project dcache by dCache.

the class OfflineJwtVerificationTest method shouldAcceptNonExpiredTokenFromTrustedOp.

@Test
public void shouldAcceptNonExpiredTokenFromTrustedOp() throws Exception {
    given(anIp("EXAMPLE").withEndpoint("https://oidc.example.org/"));
    given(anOfflineJwtVerification().withEmptyAudienceTargetProperty().withIssuer(anIssuer().withIp(identityProvider)));
    given(aJwt().withPayloadClaim("iss", "https://oidc.example.org/").withPayloadClaim("exp", Instant.now().plus(5, MINUTES)).withPayloadClaim("sub", "paul"));
    ExtractResult result = verification.extract(jwt);
    assertThat(result.idp(), is(sameInstance(identityProvider)));
    assertThat(result.claims(), hasEntry("iss", jsonString("https://oidc.example.org/")));
    assertThat(result.claims(), hasEntry("sub", jsonString("paul")));
    assertThat(result.claims(), hasKey("exp"));
}
Also used : ExtractResult(org.dcache.gplazma.oidc.ExtractResult) Test(org.junit.Test)

Example 5 with ExtractResult

use of org.dcache.gplazma.oidc.ExtractResult in project dcache by dCache.

the class OfflineJwtVerification method extract.

@Override
public ExtractResult extract(String token) throws AuthenticationException, UnableToProcess {
    if (!JsonWebToken.isCompatibleFormat(token)) {
        throw new UnableToProcess("token not JWT");
    }
    try {
        var jwt = checkValid(new JsonWebToken(token));
        var issuer = issuerOf(jwt);
        return new ExtractResult(issuer.getIdentityProvider(), jwt.getPayloadMap());
    } catch (IOException e) {
        throw new UnableToProcess(e.getMessage());
    }
}
Also used : IOException(java.io.IOException) JsonWebToken(org.dcache.gplazma.util.JsonWebToken) ExtractResult(org.dcache.gplazma.oidc.ExtractResult) UnableToProcess(org.dcache.gplazma.oidc.UnableToProcess)

Aggregations

ExtractResult (org.dcache.gplazma.oidc.ExtractResult)6 Test (org.junit.Test)4 IOException (java.io.IOException)2 JsonNode (com.fasterxml.jackson.databind.JsonNode)1 JsonNodeType (com.fasterxml.jackson.databind.node.JsonNodeType)1 Stopwatch (com.google.common.base.Stopwatch)1 Throwables (com.google.common.base.Throwables)1 CacheBuilder (com.google.common.cache.CacheBuilder)1 CacheLoader (com.google.common.cache.CacheLoader)1 LoadingCache (com.google.common.cache.LoadingCache)1 Streams (com.google.common.collect.Streams)1 Futures (com.google.common.util.concurrent.Futures)1 ListenableFuture (com.google.common.util.concurrent.ListenableFuture)1 ListenableFutureTask (com.google.common.util.concurrent.ListenableFutureTask)1 URI (java.net.URI)1 URISyntaxException (java.net.URISyntaxException)1 Duration (java.time.Duration)1 ChronoUnit (java.time.temporal.ChronoUnit)1 ArrayList (java.util.ArrayList)1 Base64 (java.util.Base64)1