Search in sources :

Example 16 with JaasContext

use of org.apache.kafka.common.security.JaasContext in project kafka by apache.

the class SaslAuthenticatorTest method startServerApiVersionsUnsupportedByClient.

private NioEchoServer startServerApiVersionsUnsupportedByClient(final SecurityProtocol securityProtocol, String saslMechanism) throws Exception {
    final ListenerName listenerName = ListenerName.forSecurityProtocol(securityProtocol);
    final Map<String, ?> configs = Collections.emptyMap();
    final JaasContext jaasContext = JaasContext.loadServerContext(listenerName, saslMechanism, configs);
    final Map<String, JaasContext> jaasContexts = Collections.singletonMap(saslMechanism, jaasContext);
    boolean isScram = ScramMechanism.isScram(saslMechanism);
    if (isScram)
        ScramCredentialUtils.createCache(credentialCache, Arrays.asList(saslMechanism));
    Supplier<ApiVersionsResponse> apiVersionSupplier = () -> {
        ApiVersionCollection versionCollection = new ApiVersionCollection(2);
        versionCollection.add(new ApiVersion().setApiKey(ApiKeys.SASL_HANDSHAKE.id).setMinVersion((short) 0).setMaxVersion((short) 100));
        versionCollection.add(new ApiVersion().setApiKey(ApiKeys.SASL_AUTHENTICATE.id).setMinVersion((short) 0).setMaxVersion((short) 100));
        return new ApiVersionsResponse(new ApiVersionsResponseData().setApiKeys(versionCollection));
    };
    SaslChannelBuilder serverChannelBuilder = new SaslChannelBuilder(Mode.SERVER, jaasContexts, securityProtocol, listenerName, false, saslMechanism, true, credentialCache, null, null, time, new LogContext(), apiVersionSupplier);
    serverChannelBuilder.configure(saslServerConfigs);
    server = new NioEchoServer(listenerName, securityProtocol, new TestSecurityConfig(saslServerConfigs), "localhost", serverChannelBuilder, credentialCache, time);
    server.start();
    return server;
}
Also used : ApiVersionCollection(org.apache.kafka.common.message.ApiVersionsResponseData.ApiVersionCollection) ApiVersionsResponse(org.apache.kafka.common.requests.ApiVersionsResponse) ApiVersion(org.apache.kafka.common.message.ApiVersionsResponseData.ApiVersion) LogContext(org.apache.kafka.common.utils.LogContext) ListenerName(org.apache.kafka.common.network.ListenerName) JaasContext(org.apache.kafka.common.security.JaasContext) NioEchoServer(org.apache.kafka.common.network.NioEchoServer) TestSecurityConfig(org.apache.kafka.common.security.TestSecurityConfig) SaslChannelBuilder(org.apache.kafka.common.network.SaslChannelBuilder) ApiVersionsResponseData(org.apache.kafka.common.message.ApiVersionsResponseData)

Example 17 with JaasContext

use of org.apache.kafka.common.security.JaasContext in project kafka by apache.

the class SaslAuthenticatorTest method startServerWithoutSaslAuthenticateHeader.

private NioEchoServer startServerWithoutSaslAuthenticateHeader(final SecurityProtocol securityProtocol, String saslMechanism) throws Exception {
    final ListenerName listenerName = ListenerName.forSecurityProtocol(securityProtocol);
    final Map<String, ?> configs = Collections.emptyMap();
    final JaasContext jaasContext = JaasContext.loadServerContext(listenerName, saslMechanism, configs);
    final Map<String, JaasContext> jaasContexts = Collections.singletonMap(saslMechanism, jaasContext);
    boolean isScram = ScramMechanism.isScram(saslMechanism);
    if (isScram)
        ScramCredentialUtils.createCache(credentialCache, Arrays.asList(saslMechanism));
    Supplier<ApiVersionsResponse> apiVersionSupplier = () -> {
        ApiVersionsResponse defaultApiVersionResponse = ApiVersionsResponse.defaultApiVersionsResponse(ApiMessageType.ListenerType.ZK_BROKER);
        ApiVersionCollection apiVersions = new ApiVersionCollection();
        for (ApiVersion apiVersion : defaultApiVersionResponse.data().apiKeys()) {
            if (apiVersion.apiKey() != ApiKeys.SASL_AUTHENTICATE.id) {
                // ApiVersion can NOT be reused in second ApiVersionCollection
                // due to the internal pointers it contains.
                apiVersions.add(apiVersion.duplicate());
            }
        }
        ApiVersionsResponseData data = new ApiVersionsResponseData().setErrorCode(Errors.NONE.code()).setThrottleTimeMs(0).setApiKeys(apiVersions);
        return new ApiVersionsResponse(data);
    };
    SaslChannelBuilder serverChannelBuilder = new SaslChannelBuilder(Mode.SERVER, jaasContexts, securityProtocol, listenerName, false, saslMechanism, true, credentialCache, null, null, time, new LogContext(), apiVersionSupplier) {

        @Override
        protected SaslServerAuthenticator buildServerAuthenticator(Map<String, ?> configs, Map<String, AuthenticateCallbackHandler> callbackHandlers, String id, TransportLayer transportLayer, Map<String, Subject> subjects, Map<String, Long> connectionsMaxReauthMsByMechanism, ChannelMetadataRegistry metadataRegistry) {
            return new SaslServerAuthenticator(configs, callbackHandlers, id, subjects, null, listenerName, securityProtocol, transportLayer, connectionsMaxReauthMsByMechanism, metadataRegistry, time, apiVersionSupplier) {

                @Override
                protected void enableKafkaSaslAuthenticateHeaders(boolean flag) {
                // Don't enable Kafka SASL_AUTHENTICATE headers
                }
            };
        }
    };
    serverChannelBuilder.configure(saslServerConfigs);
    server = new NioEchoServer(listenerName, securityProtocol, new TestSecurityConfig(saslServerConfigs), "localhost", serverChannelBuilder, credentialCache, time);
    server.start();
    return server;
}
Also used : ApiVersionCollection(org.apache.kafka.common.message.ApiVersionsResponseData.ApiVersionCollection) ApiVersionsResponse(org.apache.kafka.common.requests.ApiVersionsResponse) ApiVersion(org.apache.kafka.common.message.ApiVersionsResponseData.ApiVersion) ChannelMetadataRegistry(org.apache.kafka.common.network.ChannelMetadataRegistry) LogContext(org.apache.kafka.common.utils.LogContext) ListenerName(org.apache.kafka.common.network.ListenerName) TransportLayer(org.apache.kafka.common.network.TransportLayer) JaasContext(org.apache.kafka.common.security.JaasContext) NioEchoServer(org.apache.kafka.common.network.NioEchoServer) TestSecurityConfig(org.apache.kafka.common.security.TestSecurityConfig) SaslChannelBuilder(org.apache.kafka.common.network.SaslChannelBuilder) Map(java.util.Map) HashMap(java.util.HashMap) ApiVersionsResponseData(org.apache.kafka.common.message.ApiVersionsResponseData)

Example 18 with JaasContext

use of org.apache.kafka.common.security.JaasContext in project kafka by apache.

the class SaslAuthenticatorTest method createClientConnectionWithoutSaslAuthenticateHeader.

private void createClientConnectionWithoutSaslAuthenticateHeader(final SecurityProtocol securityProtocol, final String saslMechanism, String node) throws Exception {
    final ListenerName listenerName = ListenerName.forSecurityProtocol(securityProtocol);
    final Map<String, ?> configs = Collections.emptyMap();
    final JaasContext jaasContext = JaasContext.loadClientContext(configs);
    final Map<String, JaasContext> jaasContexts = Collections.singletonMap(saslMechanism, jaasContext);
    SaslChannelBuilder clientChannelBuilder = new SaslChannelBuilder(Mode.CLIENT, jaasContexts, securityProtocol, listenerName, false, saslMechanism, true, null, null, null, time, new LogContext(), null) {

        @Override
        protected SaslClientAuthenticator buildClientAuthenticator(Map<String, ?> configs, AuthenticateCallbackHandler callbackHandler, String id, String serverHost, String servicePrincipal, TransportLayer transportLayer, Subject subject) {
            return new SaslClientAuthenticator(configs, callbackHandler, id, subject, servicePrincipal, serverHost, saslMechanism, true, transportLayer, time, new LogContext()) {

                @Override
                protected SaslHandshakeRequest createSaslHandshakeRequest(short version) {
                    return buildSaslHandshakeRequest(saslMechanism, (short) 0);
                }

                @Override
                protected void setSaslAuthenticateAndHandshakeVersions(ApiVersionsResponse apiVersionsResponse) {
                // Don't set version so that headers are disabled
                }
            };
        }
    };
    clientChannelBuilder.configure(saslClientConfigs);
    this.selector = NetworkTestUtils.createSelector(clientChannelBuilder, time);
    InetSocketAddress addr = new InetSocketAddress("localhost", server.port());
    selector.connect(node, addr, BUFFER_SIZE, BUFFER_SIZE);
}
Also used : ApiVersionsResponse(org.apache.kafka.common.requests.ApiVersionsResponse) InetSocketAddress(java.net.InetSocketAddress) LogContext(org.apache.kafka.common.utils.LogContext) ListenerName(org.apache.kafka.common.network.ListenerName) AuthenticateCallbackHandler(org.apache.kafka.common.security.auth.AuthenticateCallbackHandler) Subject(javax.security.auth.Subject) TransportLayer(org.apache.kafka.common.network.TransportLayer) JaasContext(org.apache.kafka.common.security.JaasContext) SaslChannelBuilder(org.apache.kafka.common.network.SaslChannelBuilder) Map(java.util.Map) HashMap(java.util.HashMap)

Example 19 with JaasContext

use of org.apache.kafka.common.security.JaasContext in project kafka by apache.

the class SaslChannelBuilder method configure.

@SuppressWarnings("unchecked")
@Override
public void configure(Map<String, ?> configs) throws KafkaException {
    try {
        this.configs = configs;
        if (mode == Mode.SERVER) {
            createServerCallbackHandlers(configs);
            createConnectionsMaxReauthMsMap(configs);
        } else
            createClientCallbackHandler(configs);
        for (Map.Entry<String, AuthenticateCallbackHandler> entry : saslCallbackHandlers.entrySet()) {
            String mechanism = entry.getKey();
            entry.getValue().configure(configs, mechanism, jaasContexts.get(mechanism).configurationEntries());
        }
        Class<? extends Login> defaultLoginClass = defaultLoginClass();
        if (mode == Mode.SERVER && jaasContexts.containsKey(SaslConfigs.GSSAPI_MECHANISM)) {
            String defaultRealm;
            try {
                defaultRealm = defaultKerberosRealm();
            } catch (Exception ke) {
                defaultRealm = "";
            }
            List<String> principalToLocalRules = (List<String>) configs.get(BrokerSecurityConfigs.SASL_KERBEROS_PRINCIPAL_TO_LOCAL_RULES_CONFIG);
            if (principalToLocalRules != null)
                kerberosShortNamer = KerberosShortNamer.fromUnparsedRules(defaultRealm, principalToLocalRules);
        }
        for (Map.Entry<String, JaasContext> entry : jaasContexts.entrySet()) {
            String mechanism = entry.getKey();
            // With static JAAS configuration, use KerberosLogin if Kerberos is enabled. With dynamic JAAS configuration,
            // use KerberosLogin only for the LoginContext corresponding to GSSAPI
            LoginManager loginManager = LoginManager.acquireLoginManager(entry.getValue(), mechanism, defaultLoginClass, configs);
            loginManagers.put(mechanism, loginManager);
            Subject subject = loginManager.subject();
            subjects.put(mechanism, subject);
            if (mode == Mode.SERVER && mechanism.equals(SaslConfigs.GSSAPI_MECHANISM))
                maybeAddNativeGssapiCredentials(subject);
        }
        if (this.securityProtocol == SecurityProtocol.SASL_SSL) {
            // Disable SSL client authentication as we are using SASL authentication
            this.sslFactory = new SslFactory(mode, sslClientAuthOverride, isInterBrokerListener);
            this.sslFactory.configure(configs);
        }
    } catch (Throwable e) {
        close();
        throw new KafkaException(e);
    }
}
Also used : LoginManager(org.apache.kafka.common.security.authenticator.LoginManager) AuthenticateCallbackHandler(org.apache.kafka.common.security.auth.AuthenticateCallbackHandler) KafkaException(org.apache.kafka.common.KafkaException) GSSException(org.ietf.jgss.GSSException) IOException(java.io.IOException) Subject(javax.security.auth.Subject) SslFactory(org.apache.kafka.common.security.ssl.SslFactory) JaasContext(org.apache.kafka.common.security.JaasContext) List(java.util.List) KafkaException(org.apache.kafka.common.KafkaException) Map(java.util.Map) HashMap(java.util.HashMap)

Example 20 with JaasContext

use of org.apache.kafka.common.security.JaasContext in project kafka by apache.

the class ChannelBuilders method create.

private static ChannelBuilder create(SecurityProtocol securityProtocol, Mode mode, JaasContext.Type contextType, AbstractConfig config, ListenerName listenerName, boolean isInterBrokerListener, String clientSaslMechanism, boolean saslHandshakeRequestEnable, CredentialCache credentialCache, DelegationTokenCache tokenCache, Time time, LogContext logContext, Supplier<ApiVersionsResponse> apiVersionSupplier) {
    Map<String, Object> configs = channelBuilderConfigs(config, listenerName);
    ChannelBuilder channelBuilder;
    switch(securityProtocol) {
        case SSL:
            requireNonNullMode(mode, securityProtocol);
            channelBuilder = new SslChannelBuilder(mode, listenerName, isInterBrokerListener, logContext);
            break;
        case SASL_SSL:
        case SASL_PLAINTEXT:
            requireNonNullMode(mode, securityProtocol);
            Map<String, JaasContext> jaasContexts;
            String sslClientAuthOverride = null;
            if (mode == Mode.SERVER) {
                @SuppressWarnings("unchecked") List<String> enabledMechanisms = (List<String>) configs.get(BrokerSecurityConfigs.SASL_ENABLED_MECHANISMS_CONFIG);
                jaasContexts = new HashMap<>(enabledMechanisms.size());
                for (String mechanism : enabledMechanisms) jaasContexts.put(mechanism, JaasContext.loadServerContext(listenerName, mechanism, configs));
                // SSL client authentication is enabled in brokers for SASL_SSL only if listener-prefixed config is specified.
                if (listenerName != null && securityProtocol == SecurityProtocol.SASL_SSL) {
                    String configuredClientAuth = (String) configs.get(BrokerSecurityConfigs.SSL_CLIENT_AUTH_CONFIG);
                    String listenerClientAuth = (String) config.originalsWithPrefix(listenerName.configPrefix(), true).get(BrokerSecurityConfigs.SSL_CLIENT_AUTH_CONFIG);
                    // ssl.client.auth` cannot be dynamically altered.
                    if (listenerClientAuth == null) {
                        sslClientAuthOverride = SslClientAuth.NONE.name().toLowerCase(Locale.ROOT);
                        if (configuredClientAuth != null && !configuredClientAuth.equalsIgnoreCase(SslClientAuth.NONE.name())) {
                            log.warn("Broker configuration '{}' is applied only to SSL listeners. Listener-prefixed configuration can be used" + " to enable SSL client authentication for SASL_SSL listeners. In future releases, broker-wide option without" + " listener prefix may be applied to SASL_SSL listeners as well. All configuration options intended for specific" + " listeners should be listener-prefixed.", BrokerSecurityConfigs.SSL_CLIENT_AUTH_CONFIG);
                        }
                    }
                }
            } else {
                // Use server context for inter-broker client connections and client context for other clients
                JaasContext jaasContext = contextType == JaasContext.Type.CLIENT ? JaasContext.loadClientContext(configs) : JaasContext.loadServerContext(listenerName, clientSaslMechanism, configs);
                jaasContexts = Collections.singletonMap(clientSaslMechanism, jaasContext);
            }
            channelBuilder = new SaslChannelBuilder(mode, jaasContexts, securityProtocol, listenerName, isInterBrokerListener, clientSaslMechanism, saslHandshakeRequestEnable, credentialCache, tokenCache, sslClientAuthOverride, time, logContext, apiVersionSupplier);
            break;
        case PLAINTEXT:
            channelBuilder = new PlaintextChannelBuilder(listenerName);
            break;
        default:
            throw new IllegalArgumentException("Unexpected securityProtocol " + securityProtocol);
    }
    channelBuilder.configure(configs);
    return channelBuilder;
}
Also used : JaasContext(org.apache.kafka.common.security.JaasContext) List(java.util.List)

Aggregations

JaasContext (org.apache.kafka.common.security.JaasContext)21 HashMap (java.util.HashMap)10 ListenerName (org.apache.kafka.common.network.ListenerName)9 Map (java.util.Map)6 SaslChannelBuilder (org.apache.kafka.common.network.SaslChannelBuilder)5 TestJaasConfig (org.apache.kafka.common.security.authenticator.TestJaasConfig)5 List (java.util.List)4 Subject (javax.security.auth.Subject)4 TransportLayer (org.apache.kafka.common.network.TransportLayer)4 ApiVersionsResponse (org.apache.kafka.common.requests.ApiVersionsResponse)4 LogContext (org.apache.kafka.common.utils.LogContext)4 NioEchoServer (org.apache.kafka.common.network.NioEchoServer)3 TestSecurityConfig (org.apache.kafka.common.security.TestSecurityConfig)3 PlainLoginModule (org.apache.kafka.common.security.plain.PlainLoginModule)3 Test (org.junit.jupiter.api.Test)3 IOException (java.io.IOException)2 InetSocketAddress (java.net.InetSocketAddress)2 KafkaException (org.apache.kafka.common.KafkaException)2 ApiVersionsResponseData (org.apache.kafka.common.message.ApiVersionsResponseData)2 ApiVersion (org.apache.kafka.common.message.ApiVersionsResponseData.ApiVersion)2