Search in sources :

Example 1 with NONCE

use of io.trino.server.security.oauth2.OAuth2Service.NONCE in project trino by trinodb.

the class OAuth2Service method startOAuth2Challenge.

public Response startOAuth2Challenge(URI callbackUri, Optional<String> handlerState) {
    Instant challengeExpiration = now().plus(challengeTimeout);
    String state = newJwtBuilder().signWith(stateHmac).setAudience(STATE_AUDIENCE_UI).claim(HANDLER_STATE_CLAIM, handlerState.orElse(null)).setExpiration(Date.from(challengeExpiration)).compact();
    Optional<String> nonce;
    // since this scope is required in order to obtain the ID token which carriers the nonce back to the server
    if (scopes.contains(OPENID_SCOPE)) {
        nonce = Optional.of(randomNonce());
    } else {
        nonce = Optional.empty();
    }
    Response.ResponseBuilder response = Response.seeOther(client.getAuthorizationUri(state, callbackUri, nonce.map(OAuth2Service::hashNonce)));
    nonce.ifPresent(nce -> response.cookie(NonceCookie.create(nce, challengeExpiration)));
    return response.build();
}
Also used : OAuth2Response(io.trino.server.security.oauth2.OAuth2Client.OAuth2Response) Response(javax.ws.rs.core.Response) Instant(java.time.Instant)

Example 2 with NONCE

use of io.trino.server.security.oauth2.OAuth2Service.NONCE in project trino by trinodb.

the class OAuth2Service method finishOAuth2Challenge.

public Response finishOAuth2Challenge(String state, String code, URI callbackUri, Optional<String> nonce) {
    Optional<String> handlerState;
    try {
        Claims stateClaims = parseState(state);
        handlerState = Optional.ofNullable(stateClaims.get(HANDLER_STATE_CLAIM, String.class));
    } catch (ChallengeFailedException | RuntimeException e) {
        LOG.debug(e, "Authentication response could not be verified invalid state: state=%s", state);
        return Response.status(BAD_REQUEST).entity(getInternalFailureHtml("Authentication response could not be verified")).cookie(NonceCookie.delete()).build();
    }
    // Note: the Web UI may be disabled, so REST requests can not redirect to a success or error page inside of the Web UI
    try {
        // fetch access token
        OAuth2Response oauth2Response = client.getOAuth2Response(code, callbackUri);
        Claims parsedToken = validateAndParseOAuth2Response(oauth2Response, nonce).orElseThrow(() -> new ChallengeFailedException("invalid access token"));
        // determine expiration
        Instant validUntil = determineExpiration(oauth2Response.getValidUntil(), parsedToken.getExpiration());
        if (handlerState.isEmpty()) {
            return Response.seeOther(URI.create(UI_LOCATION)).cookie(OAuthWebUiCookie.create(oauth2Response.getAccessToken(), validUntil), NonceCookie.delete()).build();
        }
        tokenHandler.setAccessToken(handlerState.get(), oauth2Response.getAccessToken());
        Response.ResponseBuilder builder = Response.ok(getSuccessHtml());
        if (webUiOAuthEnabled) {
            builder.cookie(OAuthWebUiCookie.create(oauth2Response.getAccessToken(), validUntil));
        }
        return builder.cookie(NonceCookie.delete()).build();
    } catch (ChallengeFailedException | RuntimeException e) {
        LOG.debug(e, "Authentication response could not be verified: state=%s", state);
        handlerState.ifPresent(value -> tokenHandler.setTokenExchangeError(value, format("Authentication response could not be verified: state=%s", value)));
        return Response.status(BAD_REQUEST).cookie(NonceCookie.delete()).entity(getInternalFailureHtml("Authentication response could not be verified")).build();
    }
}
Also used : OAuth2Response(io.trino.server.security.oauth2.OAuth2Client.OAuth2Response) OAuth2Response(io.trino.server.security.oauth2.OAuth2Client.OAuth2Response) Response(javax.ws.rs.core.Response) JsonResponseHandler(io.airlift.http.client.JsonResponseHandler) GET(javax.ws.rs.HttpMethod.GET) Date(java.util.Date) AUTHORIZATION(com.google.common.net.HttpHeaders.AUTHORIZATION) JwtParser(io.jsonwebtoken.JwtParser) Random(java.util.Random) SecureRandom(java.security.SecureRandom) Duration(java.time.Duration) Map(java.util.Map) UriBuilder(javax.ws.rs.core.UriBuilder) URI(java.net.URI) OAuth2Response(io.trino.server.security.oauth2.OAuth2Client.OAuth2Response) BAD_REQUEST(javax.ws.rs.core.Response.Status.BAD_REQUEST) ImmutableSet(com.google.common.collect.ImmutableSet) Collection(java.util.Collection) Set(java.util.Set) Instant(java.time.Instant) AUDIENCE(io.jsonwebtoken.Claims.AUDIENCE) String.format(java.lang.String.format) Key(java.security.Key) Response(javax.ws.rs.core.Response) SigningKeyResolver(io.jsonwebtoken.SigningKeyResolver) OAuthWebUiCookie(io.trino.server.ui.OAuthWebUiCookie) Optional(java.util.Optional) JsonResponseHandler.createJsonResponseHandler(io.airlift.http.client.JsonResponseHandler.createJsonResponseHandler) OAuth2WebUiInstalled(io.trino.server.ui.OAuth2WebUiInstalled) HttpClient(io.airlift.http.client.HttpClient) Instant.now(java.time.Instant.now) Logger(io.airlift.log.Logger) Strings.nullToEmpty(com.google.common.base.Strings.nullToEmpty) JwtUtil.newJwtBuilder(io.trino.server.security.jwt.JwtUtil.newJwtBuilder) Claims(io.jsonwebtoken.Claims) Inject(javax.inject.Inject) Verify.verify(com.google.common.base.Verify.verify) DefaultClaims(io.jsonwebtoken.impl.DefaultClaims) Objects.requireNonNull(java.util.Objects.requireNonNull) Request(io.airlift.http.client.Request) TemporalAmount(java.time.temporal.TemporalAmount) UI_LOCATION(io.trino.server.ui.FormWebUiAuthenticationFilter.UI_LOCATION) JwtUtil.newJwtParserBuilder(io.trino.server.security.jwt.JwtUtil.newJwtParserBuilder) Keys.hmacShaKeyFor(io.jsonwebtoken.security.Keys.hmacShaKeyFor) BaseEncoding(com.google.common.io.BaseEncoding) Resources(com.google.common.io.Resources) JsonCodec.mapJsonCodec(io.airlift.json.JsonCodec.mapJsonCodec) UTF_8(java.nio.charset.StandardCharsets.UTF_8) IOException(java.io.IOException) Hashing.sha256(com.google.common.hash.Hashing.sha256) Ordering(com.google.common.collect.Ordering) VisibleForTesting(com.google.common.annotations.VisibleForTesting) Claims(io.jsonwebtoken.Claims) DefaultClaims(io.jsonwebtoken.impl.DefaultClaims) Instant(java.time.Instant)

Aggregations

OAuth2Response (io.trino.server.security.oauth2.OAuth2Client.OAuth2Response)2 Instant (java.time.Instant)2 Response (javax.ws.rs.core.Response)2 VisibleForTesting (com.google.common.annotations.VisibleForTesting)1 Strings.nullToEmpty (com.google.common.base.Strings.nullToEmpty)1 Verify.verify (com.google.common.base.Verify.verify)1 ImmutableSet (com.google.common.collect.ImmutableSet)1 Ordering (com.google.common.collect.Ordering)1 Hashing.sha256 (com.google.common.hash.Hashing.sha256)1 BaseEncoding (com.google.common.io.BaseEncoding)1 Resources (com.google.common.io.Resources)1 AUTHORIZATION (com.google.common.net.HttpHeaders.AUTHORIZATION)1 HttpClient (io.airlift.http.client.HttpClient)1 JsonResponseHandler (io.airlift.http.client.JsonResponseHandler)1 JsonResponseHandler.createJsonResponseHandler (io.airlift.http.client.JsonResponseHandler.createJsonResponseHandler)1 Request (io.airlift.http.client.Request)1 JsonCodec.mapJsonCodec (io.airlift.json.JsonCodec.mapJsonCodec)1 Logger (io.airlift.log.Logger)1 Claims (io.jsonwebtoken.Claims)1 AUDIENCE (io.jsonwebtoken.Claims.AUDIENCE)1