use of io.trino.server.security.oauth2.ChallengeFailedException 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();
}
}
use of io.trino.server.security.oauth2.ChallengeFailedException in project trino by trinodb.
the class OAuth2Authenticator method createIdentity.
@Override
protected Optional<Identity> createIdentity(String token) throws UserMappingException {
try {
Optional<Map<String, Object>> claims = service.convertTokenToClaims(token);
if (claims.isEmpty()) {
return Optional.empty();
}
String principal = (String) claims.get().get(principalField);
Identity.Builder builder = Identity.forUser(userMapping.mapUser(principal));
builder.withPrincipal(new BasicPrincipal(principal));
groupsField.flatMap(field -> Optional.ofNullable((List<String>) claims.get().get(field))).ifPresent(groups -> builder.withGroups(ImmutableSet.copyOf(groups)));
return Optional.of(builder.build());
} catch (ChallengeFailedException e) {
return Optional.empty();
}
}
use of io.trino.server.security.oauth2.ChallengeFailedException in project trino by trinodb.
the class OAuth2WebUiAuthenticationFilter method filter.
@Override
public void filter(ContainerRequestContext request) {
String path = request.getUriInfo().getRequestUri().getPath();
if (path.equals(DISABLED_LOCATION)) {
return;
}
// doesn't seem very useful if you have OAuth, and would be very complex.
if (!request.getSecurityContext().isSecure()) {
// send 401 to REST api calls and redirect to others
if (path.startsWith("/ui/api/")) {
sendWwwAuthenticate(request, "Unauthorized", ImmutableSet.of(TRINO_FORM_LOGIN));
return;
}
request.abortWith(Response.seeOther(DISABLED_LOCATION_URI).build());
return;
}
Optional<Map<String, Object>> claims;
try {
claims = getAccessToken(request);
if (claims.isEmpty()) {
needAuthentication(request);
return;
}
} catch (ChallengeFailedException e) {
LOG.debug(e, "Invalid token: %s", e.getMessage());
sendErrorMessage(request, UNAUTHORIZED, "Unauthorized");
return;
}
try {
Object principal = claims.get().get(principalField);
if (!isValidPrincipal(principal)) {
LOG.debug("Invalid principal field: %s. Expected principal to be non-empty", principalField);
sendErrorMessage(request, UNAUTHORIZED, "Unauthorized");
return;
}
String principalName = (String) principal;
Identity.Builder builder = Identity.forUser(userMapping.mapUser(principalName));
builder.withPrincipal(new BasicPrincipal(principalName));
groupsField.flatMap(field -> Optional.ofNullable((List<String>) claims.get().get(field))).ifPresent(groups -> builder.withGroups(ImmutableSet.copyOf(groups)));
setAuthenticatedIdentity(request, builder.build());
} catch (UserMappingException e) {
sendErrorMessage(request, UNAUTHORIZED, firstNonNull(e.getMessage(), "Unauthorized"));
}
}
Aggregations