Search in sources :

Example 1 with BasicPrincipal

use of io.trino.spi.security.BasicPrincipal in project trino by trinodb.

the class InsecureAuthenticator method authenticate.

@Override
public Identity authenticate(ContainerRequestContext request) throws AuthenticationException {
    Optional<BasicAuthCredentials> basicAuthCredentials = extractBasicAuthCredentials(request);
    String user;
    if (basicAuthCredentials.isPresent()) {
        if (basicAuthCredentials.get().getPassword().isPresent()) {
            throw new AuthenticationException("Password not allowed for insecure authentication", BasicAuthCredentials.AUTHENTICATE_HEADER);
        }
        user = basicAuthCredentials.get().getUser();
    } else {
        try {
            ProtocolHeaders protocolHeaders = detectProtocol(alternateHeaderName, request.getHeaders().keySet());
            user = emptyToNull(request.getHeaders().getFirst(protocolHeaders.requestUser()));
        } catch (ProtocolDetectionException e) {
            // ignored
            user = null;
        }
    }
    if (user == null) {
        throw new AuthenticationException("Basic authentication or " + TRINO_HEADERS.requestUser() + " must be sent", BasicAuthCredentials.AUTHENTICATE_HEADER);
    }
    try {
        String authenticatedUser = userMapping.mapUser(user);
        return Identity.forUser(authenticatedUser).withPrincipal(new BasicPrincipal(user)).build();
    } catch (UserMappingException e) {
        throw new AuthenticationException(e.getMessage());
    }
}
Also used : ProtocolHeaders(io.trino.client.ProtocolHeaders) BasicAuthCredentials.extractBasicAuthCredentials(io.trino.server.security.BasicAuthCredentials.extractBasicAuthCredentials) BasicPrincipal(io.trino.spi.security.BasicPrincipal) ProtocolDetectionException(io.trino.client.ProtocolDetectionException)

Example 2 with BasicPrincipal

use of io.trino.spi.security.BasicPrincipal 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();
    }
}
Also used : ImmutableSet(com.google.common.collect.ImmutableSet) UserMapping(io.trino.server.security.UserMapping) UUID(java.util.UUID) UserMapping.createUserMapping(io.trino.server.security.UserMapping.createUserMapping) BasicPrincipal(io.trino.spi.security.BasicPrincipal) String.format(java.lang.String.format) ContainerRequestContext(javax.ws.rs.container.ContainerRequestContext) Inject(javax.inject.Inject) OAuth2TokenExchangeResource.getInitiateUri(io.trino.server.security.oauth2.OAuth2TokenExchangeResource.getInitiateUri) List(java.util.List) AbstractBearerAuthenticator(io.trino.server.security.AbstractBearerAuthenticator) Identity(io.trino.spi.security.Identity) Map(java.util.Map) Objects.requireNonNull(java.util.Objects.requireNonNull) AuthenticationException(io.trino.server.security.AuthenticationException) Optional(java.util.Optional) OAuth2TokenExchangeResource.getTokenUri(io.trino.server.security.oauth2.OAuth2TokenExchangeResource.getTokenUri) URI(java.net.URI) UserMappingException(io.trino.server.security.UserMappingException) BasicPrincipal(io.trino.spi.security.BasicPrincipal) Identity(io.trino.spi.security.Identity) Map(java.util.Map)

Example 3 with BasicPrincipal

use of io.trino.spi.security.BasicPrincipal in project trino by trinodb.

the class TestWebUi method testCustomPrincipalField.

@Test
public void testCustomPrincipalField() throws Exception {
    String accessToken = createTokenBuilder().setSubject("unknown").addClaims(ImmutableMap.of("preferred_username", "test-user@email.com")).compact();
    TestingHttpServer jwkServer = createTestingJwkServer();
    jwkServer.start();
    try (TestingTrinoServer server = TestingTrinoServer.builder().setProperties(ImmutableMap.<String, String>builder().putAll(OAUTH2_PROPERTIES).put("http-server.authentication.oauth2.jwks-url", jwkServer.getBaseUrl().toString()).put("http-server.authentication.oauth2.principal-field", "preferred_username").put("http-server.authentication.oauth2.user-mapping.pattern", "(.*)@.*").buildOrThrow()).setAdditionalModule(binder -> {
        newOptionalBinder(binder, OAuth2Client.class).setBinding().toInstance(new OAuth2ClientStub(accessToken));
        jaxrsBinder(binder).bind(AuthenticatedIdentityCapturingFilter.class);
    }).build()) {
        HttpServerInfo httpServerInfo = server.getInstance(Key.get(HttpServerInfo.class));
        assertAuth2Authentication(httpServerInfo, accessToken);
        Identity identity = server.getInstance(Key.get(AuthenticatedIdentityCapturingFilter.class)).getAuthenticatedIdentity();
        assertThat(identity.getUser()).isEqualTo("test-user");
        assertThat(identity.getPrincipal()).isEqualTo(Optional.of(new BasicPrincipal("test-user@email.com")));
    } finally {
        jwkServer.stop();
    }
}
Also used : ResourceSecurity(io.trino.server.security.ResourceSecurity) X_FORWARDED_PORT(com.google.common.net.HttpHeaders.X_FORWARDED_PORT) Date(java.util.Date) ZonedDateTime(java.time.ZonedDateTime) Assertions.assertThat(org.assertj.core.api.Assertions.assertThat) Key(com.google.inject.Key) NodeInfo(io.airlift.node.NodeInfo) AUTHORIZATION(com.google.common.net.HttpHeaders.AUTHORIZATION) Test(org.testng.annotations.Test) ContainerRequestFilter(javax.ws.rs.container.ContainerRequestFilter) HttpServerConfig(io.airlift.http.server.HttpServerConfig) ContainerRequestContext(javax.ws.rs.container.ContainerRequestContext) JwsHeader(io.jsonwebtoken.JwsHeader) HttpCookie(java.net.HttpCookie) SC_SEE_OTHER(javax.servlet.http.HttpServletResponse.SC_SEE_OTHER) FormBody(okhttp3.FormBody) JwtBuilder(io.jsonwebtoken.JwtBuilder) DISABLED_LOCATION(io.trino.server.ui.FormWebUiAuthenticationFilter.DISABLED_LOCATION) URI(java.net.URI) WEB_UI(io.trino.server.security.ResourceSecurity.AccessType.WEB_UI) TestingTrinoServer(io.trino.server.testing.TestingTrinoServer) Path(java.nio.file.Path) X_FORWARDED_PROTO(com.google.common.net.HttpHeaders.X_FORWARDED_PROTO) OptionalBinder.newOptionalBinder(com.google.inject.multibindings.OptionalBinder.newOptionalBinder) Assert.assertEquals(io.trino.testing.assertions.Assert.assertEquals) PemReader(io.airlift.security.pem.PemReader) Request(okhttp3.Request) UNAUTHORIZED(javax.ws.rs.core.Response.Status.UNAUTHORIZED) ImmutableSet(com.google.common.collect.ImmutableSet) Context(javax.ws.rs.core.Context) HttpServlet(javax.servlet.http.HttpServlet) ImmutableMap(com.google.common.collect.ImmutableMap) JavaNetCookieJar(okhttp3.JavaNetCookieJar) BeforeClass(org.testng.annotations.BeforeClass) AUTHENTICATED_IDENTITY(io.trino.server.HttpRequestSessionContextFactory.AUTHENTICATED_IDENTITY) PreparedStatementEncoder(io.trino.server.protocol.PreparedStatementEncoder) GuardedBy(javax.annotation.concurrent.GuardedBy) BasicPrincipal(io.trino.spi.security.BasicPrincipal) Preconditions.checkState(com.google.common.base.Preconditions.checkState) UncheckedIOException(java.io.UncheckedIOException) SC_NOT_FOUND(javax.servlet.http.HttpServletResponse.SC_NOT_FOUND) Base64(java.util.Base64) HttpServerInfo(io.airlift.http.server.HttpServerInfo) HttpHeaders(javax.ws.rs.core.HttpHeaders) Principal(java.security.Principal) AccessControl(io.trino.security.AccessControl) PrivateKey(java.security.PrivateKey) 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) SecretKey(javax.crypto.SecretKey) Predicate.not(java.util.function.Predicate.not) ProtocolConfig(io.trino.server.ProtocolConfig) AccessDeniedException(io.trino.spi.security.AccessDeniedException) NONCE(io.trino.server.security.oauth2.OAuth2Service.NONCE) UI_LOGIN(io.trino.server.ui.FormWebUiAuthenticationFilter.UI_LOGIN) GET(javax.ws.rs.GET) JwtUtil.newJwtBuilder(io.trino.server.security.jwt.JwtUtil.newJwtBuilder) OAuth2Client(io.trino.server.security.oauth2.OAuth2Client) CALLBACK_ENDPOINT(io.trino.server.security.oauth2.OAuth2CallbackResource.CALLBACK_ENDPOINT) Hashing(com.google.common.hash.Hashing) OkHttpUtil.setupSsl(io.trino.client.OkHttpUtil.setupSsl) MINUTES(java.util.concurrent.TimeUnit.MINUTES) RequestBody(okhttp3.RequestBody) Inject(javax.inject.Inject) UI_LOGOUT(io.trino.server.ui.FormWebUiAuthenticationFilter.UI_LOGOUT) HttpServletRequest(javax.servlet.http.HttpServletRequest) Assertions.assertThatThrownBy(org.assertj.core.api.Assertions.assertThatThrownBy) Identity(io.trino.spi.security.Identity) Objects.requireNonNull(java.util.Objects.requireNonNull) Response(okhttp3.Response) HttpRequestSessionContextFactory(io.trino.server.HttpRequestSessionContextFactory) SC_UNAUTHORIZED(javax.servlet.http.HttpServletResponse.SC_UNAUTHORIZED) TestingHttpServer(io.airlift.http.server.testing.TestingHttpServer) X_FORWARDED_HOST(com.google.common.net.HttpHeaders.X_FORWARDED_HOST) Keys.hmacShaKeyFor(io.jsonwebtoken.security.Keys.hmacShaKeyFor) LOGIN_FORM(io.trino.server.ui.FormWebUiAuthenticationFilter.LOGIN_FORM) Resources(com.google.common.io.Resources) Files(java.nio.file.Files) UTF_8(java.nio.charset.StandardCharsets.UTF_8) HttpServletResponse(javax.servlet.http.HttpServletResponse) IOException(java.io.IOException) Iterables.getOnlyElement(com.google.common.collect.Iterables.getOnlyElement) File(java.io.File) PasswordAuthenticatorManager(io.trino.server.security.PasswordAuthenticatorManager) OkHttpClient(okhttp3.OkHttpClient) LOCATION(com.google.common.net.HttpHeaders.LOCATION) Paths(java.nio.file.Paths) Assert.assertTrue(org.testng.Assert.assertTrue) BasicPrincipal(io.trino.spi.security.BasicPrincipal) OAuth2Client(io.trino.server.security.oauth2.OAuth2Client) TestingHttpServer(io.airlift.http.server.testing.TestingHttpServer) Identity(io.trino.spi.security.Identity) HttpServerInfo(io.airlift.http.server.HttpServerInfo) TestingTrinoServer(io.trino.server.testing.TestingTrinoServer) Test(org.testng.annotations.Test)

Example 4 with BasicPrincipal

use of io.trino.spi.security.BasicPrincipal in project trino by trinodb.

the class LdapAuthenticator method authenticateWithUserBind.

private Principal authenticateWithUserBind(Credential credential) {
    String user = credential.getUser();
    if (containsSpecialCharacters(user)) {
        throw new AccessDeniedException("Username contains a special LDAP character");
    }
    Exception lastException = new RuntimeException();
    for (String userBindSearchPattern : userBindSearchPatterns) {
        try {
            String userDistinguishedName = replaceUser(userBindSearchPattern, user);
            if (groupAuthorizationSearchPattern.isPresent()) {
                // user password is also validated as user DN and password is used for querying LDAP
                String searchBase = userBaseDistinguishedName.orElseThrow();
                String groupSearch = replaceUser(groupAuthorizationSearchPattern.get(), user);
                if (!client.isGroupMember(searchBase, groupSearch, userDistinguishedName, credential.getPassword())) {
                    String message = format("User [%s] not a member of an authorized group", user);
                    log.debug("%s", message);
                    throw new AccessDeniedException(message);
                }
            } else {
                client.validatePassword(userDistinguishedName, credential.getPassword());
            }
            log.debug("Authentication successful for user [%s]", user);
            return new BasicPrincipal(user);
        } catch (NamingException | AccessDeniedException e) {
            lastException = e;
        }
    }
    log.debug(lastException, "Authentication failed for user [%s], %s", user, lastException.getMessage());
    if (lastException instanceof AccessDeniedException) {
        throw (AccessDeniedException) lastException;
    }
    throw new RuntimeException("Authentication error");
}
Also used : AccessDeniedException(io.trino.spi.security.AccessDeniedException) BasicPrincipal(io.trino.spi.security.BasicPrincipal) NamingException(javax.naming.NamingException) AccessDeniedException(io.trino.spi.security.AccessDeniedException) NamingException(javax.naming.NamingException) UncheckedExecutionException(com.google.common.util.concurrent.UncheckedExecutionException)

Example 5 with BasicPrincipal

use of io.trino.spi.security.BasicPrincipal 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"));
    }
}
Also used : Logger(io.airlift.log.Logger) OAuth2Service(io.trino.server.security.oauth2.OAuth2Service) TRINO_FORM_LOGIN(io.trino.server.ui.FormWebUiAuthenticationFilter.TRINO_FORM_LOGIN) CALLBACK_ENDPOINT(io.trino.server.security.oauth2.OAuth2CallbackResource.CALLBACK_ENDPOINT) ServletSecurityUtils.sendWwwAuthenticate(io.trino.server.ServletSecurityUtils.sendWwwAuthenticate) ContainerRequestContext(javax.ws.rs.container.ContainerRequestContext) Inject(javax.inject.Inject) ServletSecurityUtils.sendErrorMessage(io.trino.server.ServletSecurityUtils.sendErrorMessage) ServletSecurityUtils.setAuthenticatedIdentity(io.trino.server.ServletSecurityUtils.setAuthenticatedIdentity) Identity(io.trino.spi.security.Identity) Map(java.util.Map) Objects.requireNonNull(java.util.Objects.requireNonNull) DISABLED_LOCATION(io.trino.server.ui.FormWebUiAuthenticationFilter.DISABLED_LOCATION) UserMappingException(io.trino.server.security.UserMappingException) UNAUTHORIZED(javax.ws.rs.core.Response.Status.UNAUTHORIZED) ImmutableSet(com.google.common.collect.ImmutableSet) UserMapping(io.trino.server.security.UserMapping) DISABLED_LOCATION_URI(io.trino.server.ui.FormWebUiAuthenticationFilter.DISABLED_LOCATION_URI) ChallengeFailedException(io.trino.server.security.oauth2.ChallengeFailedException) BasicPrincipal(io.trino.spi.security.BasicPrincipal) OAuth2Config(io.trino.server.security.oauth2.OAuth2Config) List(java.util.List) Response(javax.ws.rs.core.Response) OAUTH2_COOKIE(io.trino.server.ui.OAuthWebUiCookie.OAUTH2_COOKIE) Optional(java.util.Optional) JwtException(io.jsonwebtoken.JwtException) MoreObjects.firstNonNull(com.google.common.base.MoreObjects.firstNonNull) BasicPrincipal(io.trino.spi.security.BasicPrincipal) ChallengeFailedException(io.trino.server.security.oauth2.ChallengeFailedException) UserMappingException(io.trino.server.security.UserMappingException) ServletSecurityUtils.setAuthenticatedIdentity(io.trino.server.ServletSecurityUtils.setAuthenticatedIdentity) Identity(io.trino.spi.security.Identity) Map(java.util.Map)

Aggregations

BasicPrincipal (io.trino.spi.security.BasicPrincipal)12 DisposableSubContext (io.trino.plugin.password.ldap.TestingOpenLdapServer.DisposableSubContext)6 AccessDeniedException (io.trino.spi.security.AccessDeniedException)6 Test (org.testng.annotations.Test)6 ImmutableSet (com.google.common.collect.ImmutableSet)3 Identity (io.trino.spi.security.Identity)3 Objects.requireNonNull (java.util.Objects.requireNonNull)3 Optional (java.util.Optional)3 Inject (javax.inject.Inject)3 ContainerRequestContext (javax.ws.rs.container.ContainerRequestContext)3 Duration (io.airlift.units.Duration)2 URI (java.net.URI)2 MoreObjects.firstNonNull (com.google.common.base.MoreObjects.firstNonNull)1 Preconditions.checkState (com.google.common.base.Preconditions.checkState)1 CacheBuilder (com.google.common.cache.CacheBuilder)1 ImmutableMap (com.google.common.collect.ImmutableMap)1 Iterables.getOnlyElement (com.google.common.collect.Iterables.getOnlyElement)1 Escaper (com.google.common.escape.Escaper)1 Hashing (com.google.common.hash.Hashing)1 Resources (com.google.common.io.Resources)1