Search in sources :

Example 1 with AuthData

use of org.apache.pulsar.common.api.AuthData in project starlight-for-kafka by datastax.

the class OauthLoginCallbackHandler method handleCallback.

private void handleCallback(OAuthBearerTokenCallback callback) throws IOException {
    if (callback.token() != null) {
        throw new IllegalArgumentException("Callback had a token already");
    }
    try (Authentication authentication = AuthenticationFactoryOAuth2.clientCredentials(clientConfig.getIssuerUrl(), clientConfig.getCredentialsUrl(), clientConfig.getAudience())) {
        authentication.start();
        final AuthenticationDataProvider provider = authentication.getAuthData();
        final AuthData authData = provider.authenticate(AuthData.INIT_AUTH_DATA);
        callback.token(new OAuthBearerToken() {

            @Override
            public String value() {
                return new String(authData.getBytes(), StandardCharsets.UTF_8);
            }

            @Override
            public Set<String> scope() {
                return Collections.singleton(DEFAULT_SCOPE_CLAIM_NAME);
            }

            @Override
            public long lifetimeMs() {
                // TODO: convert "exp" claim to ms.
                return Long.MAX_VALUE;
            }

            @Override
            public String principalName() {
                return DEFAULT_PRINCIPAL_CLAIM_NAME;
            }

            @Override
            public Long startTimeMs() {
                // TODO: convert "iat" claim to ms.
                return Long.MAX_VALUE;
            }
        });
    } catch (PulsarClientException | AuthenticationException e) {
        throw new KafkaException(e);
    }
}
Also used : AuthenticationDataProvider(org.apache.pulsar.client.api.AuthenticationDataProvider) AuthData(org.apache.pulsar.common.api.AuthData) Set(java.util.Set) AuthenticationException(javax.naming.AuthenticationException) Authentication(org.apache.pulsar.client.api.Authentication) OAuthBearerToken(org.apache.kafka.common.security.oauthbearer.OAuthBearerToken) PulsarClientException(org.apache.pulsar.client.api.PulsarClientException) KafkaException(org.apache.kafka.common.KafkaException)

Example 2 with AuthData

use of org.apache.pulsar.common.api.AuthData in project pulsar by apache.

the class ServerCnx method handleConnect.

@Override
protected void handleConnect(CommandConnect connect) {
    checkArgument(state == State.Start);
    if (log.isDebugEnabled()) {
        log.debug("Received CONNECT from {}, auth enabled: {}:" + " has original principal = {}, original principal = {}", remoteAddress, service.isAuthenticationEnabled(), connect.hasOriginalPrincipal(), connect.hasOriginalPrincipal() ? connect.getOriginalPrincipal() : null);
    }
    String clientVersion = connect.getClientVersion();
    int clientProtocolVersion = connect.getProtocolVersion();
    features = new FeatureFlags();
    if (connect.hasFeatureFlags()) {
        features.copyFrom(connect.getFeatureFlags());
    }
    if (!service.isAuthenticationEnabled()) {
        completeConnect(clientProtocolVersion, clientVersion);
        return;
    }
    try {
        byte[] authData = connect.hasAuthData() ? connect.getAuthData() : emptyArray;
        AuthData clientData = AuthData.of(authData);
        // init authentication
        if (connect.hasAuthMethodName()) {
            authMethod = connect.getAuthMethodName();
        } else if (connect.hasAuthMethod()) {
            // Legacy client is passing enum
            authMethod = connect.getAuthMethod().name().substring(10).toLowerCase();
        } else {
            authMethod = "none";
        }
        authenticationProvider = getBrokerService().getAuthenticationService().getAuthenticationProvider(authMethod);
        // In AuthenticationDisabled, it will set authMethod "none".
        if (authenticationProvider == null) {
            authRole = getBrokerService().getAuthenticationService().getAnonymousUserRole().orElseThrow(() -> new AuthenticationException("No anonymous role, and no authentication provider configured"));
            completeConnect(clientProtocolVersion, clientVersion);
            return;
        }
        // init authState and other var
        ChannelHandler sslHandler = ctx.channel().pipeline().get(PulsarChannelInitializer.TLS_HANDLER);
        SSLSession sslSession = null;
        if (sslHandler != null) {
            sslSession = ((SslHandler) sslHandler).engine().getSession();
        }
        authState = authenticationProvider.newAuthState(clientData, remoteAddress, sslSession);
        if (log.isDebugEnabled()) {
            log.debug("[{}] Authenticate role : {}", remoteAddress, authState != null ? authState.getAuthRole() : null);
        }
        state = doAuthentication(clientData, clientProtocolVersion, clientVersion);
        // 3. no credentials were passed
        if (connect.hasOriginalPrincipal() && service.getPulsar().getConfig().isAuthenticateOriginalAuthData()) {
            // init authentication
            String originalAuthMethod;
            if (connect.hasOriginalAuthMethod()) {
                originalAuthMethod = connect.getOriginalAuthMethod();
            } else {
                originalAuthMethod = "none";
            }
            AuthenticationProvider originalAuthenticationProvider = getBrokerService().getAuthenticationService().getAuthenticationProvider(originalAuthMethod);
            if (originalAuthenticationProvider == null) {
                throw new AuthenticationException(String.format("Can't find AuthenticationProvider for original role" + " using auth method [%s] is not available", originalAuthMethod));
            }
            originalAuthState = originalAuthenticationProvider.newAuthState(AuthData.of(connect.getOriginalAuthData().getBytes()), remoteAddress, sslSession);
            originalAuthData = originalAuthState.getAuthDataSource();
            originalPrincipal = originalAuthState.getAuthRole();
            if (log.isDebugEnabled()) {
                log.debug("[{}] Authenticate original role : {}", remoteAddress, originalPrincipal);
            }
        } else {
            originalPrincipal = connect.hasOriginalPrincipal() ? connect.getOriginalPrincipal() : null;
            if (log.isDebugEnabled()) {
                log.debug("[{}] Authenticate original role (forwarded from proxy): {}", remoteAddress, originalPrincipal);
            }
        }
    } catch (Exception e) {
        service.getPulsarStats().recordConnectionCreateFail();
        logAuthException(remoteAddress, "connect", getPrincipal(), Optional.empty(), e);
        String msg = "Unable to authenticate";
        ctx.writeAndFlush(Commands.newError(-1, ServerError.AuthenticationError, msg));
        close();
    }
}
Also used : AuthData(org.apache.pulsar.common.api.AuthData) AuthenticationException(javax.naming.AuthenticationException) SSLSession(javax.net.ssl.SSLSession) AuthenticationProvider(org.apache.pulsar.broker.authentication.AuthenticationProvider) FeatureFlags(org.apache.pulsar.common.api.proto.FeatureFlags) ChannelHandler(io.netty.channel.ChannelHandler) SslHandler(io.netty.handler.ssl.SslHandler) ServiceUnitNotReadyException(org.apache.pulsar.broker.service.BrokerServiceException.ServiceUnitNotReadyException) RestException(org.apache.pulsar.broker.web.RestException) InterceptException(org.apache.pulsar.common.intercept.InterceptException) TopicNotFoundException(org.apache.pulsar.broker.service.BrokerServiceException.TopicNotFoundException) ServerMetadataException(org.apache.pulsar.broker.service.BrokerServiceException.ServerMetadataException) AuthenticationException(javax.naming.AuthenticationException) PulsarClientException(org.apache.pulsar.client.api.PulsarClientException) SubscriptionNotFoundException(org.apache.pulsar.broker.service.BrokerServiceException.SubscriptionNotFoundException) ManagedLedgerException(org.apache.bookkeeper.mledger.ManagedLedgerException) IncompatibleSchemaException(org.apache.pulsar.broker.service.schema.exceptions.IncompatibleSchemaException) CoordinatorException(org.apache.pulsar.transaction.coordinator.exceptions.CoordinatorException) NoSuchElementException(java.util.NoSuchElementException) ConsumerBusyException(org.apache.pulsar.broker.service.BrokerServiceException.ConsumerBusyException)

Example 3 with AuthData

use of org.apache.pulsar.common.api.AuthData in project pulsar by apache.

the class SaslAuthenticateTest method testSaslServerAndClientAuth.

// Test sasl server/client auth.
@Test
public void testSaslServerAndClientAuth() throws Exception {
    log.info("-- {} -- start", methodName);
    String hostName = "localhost";
    // prepare client and server side resource
    AuthenticationDataProvider dataProvider = authSasl.getAuthData(hostName);
    AuthenticationProviderList providerList = (AuthenticationProviderList) (pulsar.getBrokerService().getAuthenticationService().getAuthenticationProvider(SaslConstants.AUTH_METHOD_NAME));
    AuthenticationProviderSasl saslServer = (AuthenticationProviderSasl) providerList.getProviders().get(0);
    AuthenticationState authState = saslServer.newAuthState(null, null, null);
    // auth between server and client.
    // first time auth
    AuthData initData1 = dataProvider.authenticate(AuthData.INIT_AUTH_DATA);
    AuthData serverData1 = authState.authenticate(initData1);
    boolean complete = authState.isComplete();
    assertFalse(complete);
    // second time auth, completed
    AuthData initData2 = dataProvider.authenticate(serverData1);
    AuthData serverData2 = authState.authenticate(initData2);
    complete = authState.isComplete();
    assertTrue(complete);
    assertNull(serverData2.getBytes());
    // if completed, server could not auth again.
    try {
        authState.authenticate(initData2);
        fail("Expected fail because auth completed for authState");
    } catch (Exception e) {
    // expected
    }
    // another server could not serve old client
    try {
        AuthenticationState authState2 = saslServer.newAuthState(null, null, null);
        AuthData serverData3 = authState2.authenticate(initData1);
        fail("Expected fail. server is auth old client data");
    } catch (Exception e) {
    // expected
    }
    log.info("-- {} -- end", methodName);
}
Also used : AuthenticationDataProvider(org.apache.pulsar.client.api.AuthenticationDataProvider) AuthData(org.apache.pulsar.common.api.AuthData) Test(org.testng.annotations.Test)

Example 4 with AuthData

use of org.apache.pulsar.common.api.AuthData in project pulsar by apache.

the class ServerCnx method refreshAuthenticationCredentials.

public void refreshAuthenticationCredentials() {
    AuthenticationState authState = this.originalAuthState != null ? originalAuthState : this.authState;
    if (authState == null) {
        // Authentication is disabled or there's no local state to refresh
        return;
    } else if (getState() != State.Connected || !isActive) {
        // Connection is either still being established or already closed.
        return;
    } else if (!authState.isExpired()) {
        // Credentials are still valid. Nothing to do at this point
        return;
    } else if (originalPrincipal != null && originalAuthState == null) {
        log.info("[{}] Cannot revalidate user credential when using proxy and" + " not forwarding the credentials. Closing connection", remoteAddress);
        return;
    }
    ctx.executor().execute(SafeRun.safeRun(() -> {
        log.info("[{}] Refreshing authentication credentials for originalPrincipal {} and authRole {}", remoteAddress, originalPrincipal, this.authRole);
        if (!supportsAuthenticationRefresh()) {
            log.warn("[{}] Closing connection because client doesn't support auth credentials refresh", remoteAddress);
            ctx.close();
            return;
        }
        if (pendingAuthChallengeResponse) {
            log.warn("[{}] Closing connection after timeout on refreshing auth credentials", remoteAddress);
            ctx.close();
            return;
        }
        try {
            AuthData brokerData = authState.refreshAuthentication();
            ctx.writeAndFlush(Commands.newAuthChallenge(authMethod, brokerData, getRemoteEndpointProtocolVersion()));
            if (log.isDebugEnabled()) {
                log.debug("[{}] Sent auth challenge to client to refresh credentials with method: {}.", remoteAddress, authMethod);
            }
            pendingAuthChallengeResponse = true;
        } catch (AuthenticationException e) {
            log.warn("[{}] Failed to refresh authentication: {}", remoteAddress, e);
            ctx.close();
        }
    }));
}
Also used : AuthData(org.apache.pulsar.common.api.AuthData) AuthenticationException(javax.naming.AuthenticationException) AuthenticationState(org.apache.pulsar.broker.authentication.AuthenticationState)

Example 5 with AuthData

use of org.apache.pulsar.common.api.AuthData in project pulsar by apache.

the class ServerCnxTest method testConnectCommandWithAuthenticationPositive.

@Test(timeOut = 30000)
public void testConnectCommandWithAuthenticationPositive() throws Exception {
    AuthenticationService authenticationService = mock(AuthenticationService.class);
    AuthenticationProvider authenticationProvider = mock(AuthenticationProvider.class);
    AuthenticationState authenticationState = mock(AuthenticationState.class);
    AuthenticationDataSource authenticationDataSource = mock(AuthenticationDataSource.class);
    AuthData authData = AuthData.of(null);
    doReturn(authenticationService).when(brokerService).getAuthenticationService();
    doReturn(authenticationProvider).when(authenticationService).getAuthenticationProvider(Mockito.anyString());
    doReturn(authenticationState).when(authenticationProvider).newAuthState(Mockito.any(), Mockito.any(), Mockito.any());
    doReturn(authData).when(authenticationState).authenticate(authData);
    doReturn(true).when(authenticationState).isComplete();
    doReturn("appid1").when(authenticationState).getAuthRole();
    doReturn(true).when(brokerService).isAuthenticationEnabled();
    resetChannel();
    assertTrue(channel.isActive());
    assertEquals(serverCnx.getState(), State.Start);
    // test server response to CONNECT
    ByteBuf clientCommand = Commands.newConnect("none", "", null);
    channel.writeInbound(clientCommand);
    assertEquals(serverCnx.getState(), State.Connected);
    assertTrue(getResponse() instanceof CommandConnected);
    channel.finish();
}
Also used : AuthData(org.apache.pulsar.common.api.AuthData) CommandConnected(org.apache.pulsar.common.api.proto.CommandConnected) AuthenticationProvider(org.apache.pulsar.broker.authentication.AuthenticationProvider) AuthenticationDataSource(org.apache.pulsar.broker.authentication.AuthenticationDataSource) ByteBuf(io.netty.buffer.ByteBuf) AuthenticationService(org.apache.pulsar.broker.authentication.AuthenticationService) AuthenticationState(org.apache.pulsar.broker.authentication.AuthenticationState) Test(org.testng.annotations.Test)

Aggregations

AuthData (org.apache.pulsar.common.api.AuthData)49 AuthenticationException (javax.naming.AuthenticationException)17 PulsarClientException (org.apache.pulsar.client.api.PulsarClientException)17 AuthenticationState (org.apache.pulsar.broker.authentication.AuthenticationState)11 Test (org.testng.annotations.Test)9 AuthenticationProvider (org.apache.pulsar.broker.authentication.AuthenticationProvider)8 ByteBuf (io.netty.buffer.ByteBuf)6 ChannelHandler (io.netty.channel.ChannelHandler)6 SslHandler (io.netty.handler.ssl.SslHandler)6 NoSuchElementException (java.util.NoSuchElementException)6 SSLSession (javax.net.ssl.SSLSession)6 ManagedLedgerException (org.apache.bookkeeper.mledger.ManagedLedgerException)6 PulsarServerException (org.apache.pulsar.broker.PulsarServerException)6 ConsumerBusyException (org.apache.pulsar.broker.service.BrokerServiceException.ConsumerBusyException)6 ServerMetadataException (org.apache.pulsar.broker.service.BrokerServiceException.ServerMetadataException)6 ServiceUnitNotReadyException (org.apache.pulsar.broker.service.BrokerServiceException.ServiceUnitNotReadyException)6 SubscriptionNotFoundException (org.apache.pulsar.broker.service.BrokerServiceException.SubscriptionNotFoundException)6 TopicNotFoundException (org.apache.pulsar.broker.service.BrokerServiceException.TopicNotFoundException)6 IncompatibleSchemaException (org.apache.pulsar.broker.service.schema.exceptions.IncompatibleSchemaException)6 RestException (org.apache.pulsar.broker.web.RestException)6