Search in sources :

Example 1 with UI_LOCATION

use of io.trino.server.ui.FormWebUiAuthenticationFilter.UI_LOCATION 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)

Example 2 with UI_LOCATION

use of io.trino.server.ui.FormWebUiAuthenticationFilter.UI_LOCATION in project trino by trinodb.

the class TestResourceSecurity method testOAuth2Groups.

@Test(dataProvider = "groups")
public void testOAuth2Groups(Optional<Set<String>> groups) throws Exception {
    try (TokenServer tokenServer = new TokenServer(Optional.empty());
        TestingTrinoServer server = TestingTrinoServer.builder().setProperties(ImmutableMap.<String, String>builder().putAll(SECURE_PROPERTIES).put("web-ui.enabled", "true").put("http-server.authentication.type", "oauth2").putAll(getOAuth2Properties(tokenServer)).put("http-server.authentication.oauth2.groups-field", GROUPS_CLAIM).buildOrThrow()).setAdditionalModule(oauth2Module(tokenServer)).build()) {
        server.getInstance(Key.get(AccessControlManager.class)).addSystemAccessControl(TestSystemAccessControl.NO_IMPERSONATION);
        HttpServerInfo httpServerInfo = server.getInstance(Key.get(HttpServerInfo.class));
        String accessToken = tokenServer.issueAccessToken(groups);
        OkHttpClient clientWithOAuthToken = client.newBuilder().authenticator((route, response) -> response.request().newBuilder().header(AUTHORIZATION, "Bearer " + accessToken).build()).build();
        assertAuthenticationAutomatic(httpServerInfo.getHttpsUri(), clientWithOAuthToken);
        try (Response response = clientWithOAuthToken.newCall(new Request.Builder().url(getLocation(httpServerInfo.getHttpsUri(), "/protocol/identity")).build()).execute()) {
            assertEquals(response.code(), SC_OK);
            assertEquals(response.header("user"), TEST_USER);
            assertEquals(response.header("principal"), TEST_USER);
            assertEquals(response.header("groups"), groups.map(TestResource::toHeader).orElse(""));
        }
        OkHttpClient clientWithOAuthCookie = client.newBuilder().cookieJar(new CookieJar() {

            @Override
            public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
            }

            @Override
            public List<Cookie> loadForRequest(HttpUrl url) {
                return ImmutableList.of(new Cookie.Builder().domain(httpServerInfo.getHttpsUri().getHost()).path(UI_LOCATION).name(OAUTH2_COOKIE).value(accessToken).httpOnly().secure().build());
            }
        }).build();
        try (Response response = clientWithOAuthCookie.newCall(new Request.Builder().url(getLocation(httpServerInfo.getHttpsUri(), "/ui/api/identity")).build()).execute()) {
            assertEquals(response.code(), SC_OK);
            assertEquals(response.header("user"), TEST_USER);
            assertEquals(response.header("principal"), TEST_USER);
            assertEquals(response.header("groups"), groups.map(TestResource::toHeader).orElse(""));
        }
    }
}
Also used : AccessDeniedException.denyReadSystemInformationAccess(io.trino.spi.security.AccessDeniedException.denyReadSystemInformationAccess) JsonProperty(com.fasterxml.jackson.annotation.JsonProperty) AccessControlManager(io.trino.security.AccessControlManager) ZonedDateTime(java.time.ZonedDateTime) NodeInfo(io.airlift.node.NodeInfo) Test(org.testng.annotations.Test) HttpServerConfig(io.airlift.http.server.HttpServerConfig) SystemSecurityContext(io.trino.spi.security.SystemSecurityContext) JwsHeader(io.jsonwebtoken.JwsHeader) HttpCookie(java.net.HttpCookie) Matcher(java.util.regex.Matcher) JwtBuilder(io.jsonwebtoken.JwtBuilder) Map(java.util.Map) Path(java.nio.file.Path) Assert.assertEquals(io.trino.testing.assertions.Assert.assertEquals) PemReader(io.airlift.security.pem.PemReader) CookieJar(okhttp3.CookieJar) Request(okhttp3.Request) HttpServlet(javax.servlet.http.HttpServlet) SET_COOKIE(javax.ws.rs.core.HttpHeaders.SET_COOKIE) JavaNetCookieJar(okhttp3.JavaNetCookieJar) Set(java.util.Set) PreparedStatementEncoder(io.trino.server.protocol.PreparedStatementEncoder) BasicPrincipal(io.trino.spi.security.BasicPrincipal) HttpServerInfo(io.airlift.http.server.HttpServerInfo) AccessControl(io.trino.security.AccessControl) PrivateKey(java.security.PrivateKey) SecretKey(javax.crypto.SecretKey) ProtocolConfig(io.trino.server.ProtocolConfig) AccessDeniedException(io.trino.spi.security.AccessDeniedException) NONCE(io.trino.server.security.oauth2.OAuth2Service.NONCE) GET(javax.ws.rs.GET) OkHttpUtil.setupSsl(io.trino.client.OkHttpUtil.setupSsl) MINUTES(java.util.concurrent.TimeUnit.MINUTES) LOCATION(javax.ws.rs.core.HttpHeaders.LOCATION) HttpServletRequest(javax.servlet.http.HttpServletRequest) Identity(io.trino.spi.security.Identity) Response(okhttp3.Response) SC_UNAUTHORIZED(javax.servlet.http.HttpServletResponse.SC_UNAUTHORIZED) Resources(com.google.common.io.Resources) Files(java.nio.file.Files) IOException(java.io.IOException) Iterables.getOnlyElement(com.google.common.collect.Iterables.getOnlyElement) File(java.io.File) WWW_AUTHENTICATE(javax.ws.rs.core.HttpHeaders.WWW_AUTHENTICATE) OkHttpClient(okhttp3.OkHttpClient) ChronoUnit(java.time.temporal.ChronoUnit) Paths(java.nio.file.Paths) OAUTH2_COOKIE(io.trino.server.ui.OAuthWebUiCookie.OAUTH2_COOKIE) AllowAllSystemAccessControl(io.trino.plugin.base.security.AllowAllSystemAccessControl) Module(com.google.inject.Module) AUTHENTICATED_USER(io.trino.server.security.ResourceSecurity.AccessType.AUTHENTICATED_USER) Date(java.util.Date) Assertions.assertThat(org.assertj.core.api.Assertions.assertThat) Key(com.google.inject.Key) AUTHORIZATION(com.google.common.net.HttpHeaders.AUTHORIZATION) SC_SEE_OTHER(javax.servlet.http.HttpServletResponse.SC_SEE_OTHER) URI(java.net.URI) WEB_UI(io.trino.server.security.ResourceSecurity.AccessType.WEB_UI) TestingTrinoServer(io.trino.server.testing.TestingTrinoServer) OptionalBinder.newOptionalBinder(com.google.inject.multibindings.OptionalBinder.newOptionalBinder) ImmutableSet(com.google.common.collect.ImmutableSet) Context(javax.ws.rs.core.Context) ImmutableMap(com.google.common.collect.ImmutableMap) BeforeClass(org.testng.annotations.BeforeClass) Assert.assertNotNull(org.testng.Assert.assertNotNull) Credentials(okhttp3.Credentials) Collectors(java.util.stream.Collectors) String.format(java.lang.String.format) Base64(java.util.Base64) List(java.util.List) HttpHeaders(javax.ws.rs.core.HttpHeaders) Principal(java.security.Principal) CookieManager(java.net.CookieManager) SC_OK(javax.servlet.http.HttpServletResponse.SC_OK) HttpUriBuilder.uriBuilderFrom(io.airlift.http.client.HttpUriBuilder.uriBuilderFrom) JaxrsBinder.jaxrsBinder(io.airlift.jaxrs.JaxrsBinder.jaxrsBinder) MetadataManager.createTestMetadataManager(io.trino.metadata.MetadataManager.createTestMetadataManager) Optional(java.util.Optional) MoreObjects.firstNonNull(com.google.common.base.MoreObjects.firstNonNull) Pattern(java.util.regex.Pattern) HttpUrl(okhttp3.HttpUrl) Instant.now(java.time.Instant.now) DataProvider(org.testng.annotations.DataProvider) JwtUtil.newJwtBuilder(io.trino.server.security.jwt.JwtUtil.newJwtBuilder) OAuth2Client(io.trino.server.security.oauth2.OAuth2Client) Headers(okhttp3.Headers) AtomicReference(java.util.concurrent.atomic.AtomicReference) Inject(javax.inject.Inject) Cookie(okhttp3.Cookie) ImmutableList(com.google.common.collect.ImmutableList) Objects.requireNonNull(java.util.Objects.requireNonNull) HttpRequestSessionContextFactory(io.trino.server.HttpRequestSessionContextFactory) UI_LOCATION(io.trino.server.ui.FormWebUiAuthenticationFilter.UI_LOCATION) TestingHttpServer(io.airlift.http.server.testing.TestingHttpServer) Keys.hmacShaKeyFor(io.jsonwebtoken.security.Keys.hmacShaKeyFor) AccessDeniedException.denyImpersonateUser(io.trino.spi.security.AccessDeniedException.denyImpersonateUser) UTF_8(java.nio.charset.StandardCharsets.UTF_8) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) HttpServletResponse(javax.servlet.http.HttpServletResponse) SC_FORBIDDEN(javax.servlet.http.HttpServletResponse.SC_FORBIDDEN) Assert.assertTrue(org.testng.Assert.assertTrue) TRINO_HEADERS(io.trino.client.ProtocolHeaders.TRINO_HEADERS) HttpCookie(java.net.HttpCookie) Cookie(okhttp3.Cookie) OkHttpClient(okhttp3.OkHttpClient) JwtBuilder(io.jsonwebtoken.JwtBuilder) JwtUtil.newJwtBuilder(io.trino.server.security.jwt.JwtUtil.newJwtBuilder) HttpUrl(okhttp3.HttpUrl) Response(okhttp3.Response) HttpServletResponse(javax.servlet.http.HttpServletResponse) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList) CookieJar(okhttp3.CookieJar) JavaNetCookieJar(okhttp3.JavaNetCookieJar) HttpServerInfo(io.airlift.http.server.HttpServerInfo) TestingTrinoServer(io.trino.server.testing.TestingTrinoServer) Test(org.testng.annotations.Test)

Aggregations

ImmutableSet (com.google.common.collect.ImmutableSet)2 Resources (com.google.common.io.Resources)2 AUTHORIZATION (com.google.common.net.HttpHeaders.AUTHORIZATION)2 Keys.hmacShaKeyFor (io.jsonwebtoken.security.Keys.hmacShaKeyFor)2 JwtUtil.newJwtBuilder (io.trino.server.security.jwt.JwtUtil.newJwtBuilder)2 UI_LOCATION (io.trino.server.ui.FormWebUiAuthenticationFilter.UI_LOCATION)2 IOException (java.io.IOException)2 String.format (java.lang.String.format)2 URI (java.net.URI)2 UTF_8 (java.nio.charset.StandardCharsets.UTF_8)2 Instant.now (java.time.Instant.now)2 Date (java.util.Date)2 Map (java.util.Map)2 Objects.requireNonNull (java.util.Objects.requireNonNull)2 Optional (java.util.Optional)2 Set (java.util.Set)2 Inject (javax.inject.Inject)2 JsonProperty (com.fasterxml.jackson.annotation.JsonProperty)1 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)1 VisibleForTesting (com.google.common.annotations.VisibleForTesting)1