use of org.apache.kafka.common.requests.ApiVersionsResponse in project kafka by apache.
the class SaslAuthenticatorTest method testApiVersionsRequestWithUnsupportedVersion.
/**
* Tests that unsupported version of ApiVersionsRequest before SASL handshake request
* returns error response and does not result in authentication failure. This test
* is similar to {@link #testUnauthenticatedApiVersionsRequest(SecurityProtocol)}
* where a non-SASL client is used to send requests that are processed by
* {@link SaslServerAuthenticator} of the server prior to client authentication.
*/
@Test
public void testApiVersionsRequestWithUnsupportedVersion() throws Exception {
SecurityProtocol securityProtocol = SecurityProtocol.SASL_PLAINTEXT;
configureMechanisms("PLAIN", Arrays.asList("PLAIN"));
server = createEchoServer(securityProtocol);
// Send ApiVersionsRequest with unsupported version and validate error response.
String node = "1";
createClientConnection(SecurityProtocol.PLAINTEXT, node);
RequestHeader header = new RequestHeader(ApiKeys.API_VERSIONS.id, Short.MAX_VALUE, "someclient", 1);
ApiVersionsRequest request = new ApiVersionsRequest.Builder().build();
selector.send(request.toSend(node, header));
ByteBuffer responseBuffer = waitForResponse();
ResponseHeader.parse(responseBuffer);
ApiVersionsResponse response = ApiVersionsResponse.parse(responseBuffer, (short) 0);
assertEquals(Errors.UNSUPPORTED_VERSION, response.error());
// Send ApiVersionsRequest with a supported version. This should succeed.
sendVersionRequestReceiveResponse(node);
// Test that client can authenticate successfully
sendHandshakeRequestReceiveResponse(node);
authenticateUsingSaslPlainAndCheckConnection(node);
}
use of org.apache.kafka.common.requests.ApiVersionsResponse in project apache-kafka-on-k8s by banzaicloud.
the class NetworkClientTest method setExpectedApiVersionsResponse.
private void setExpectedApiVersionsResponse() {
ApiVersionsResponse response = ApiVersionsResponse.defaultApiVersionsResponse();
short apiVersionsResponseVersion = response.apiVersion(ApiKeys.API_VERSIONS.id).maxVersion;
ByteBuffer buffer = response.serialize(apiVersionsResponseVersion, new ResponseHeader(0));
selector.delayedReceive(new DelayedReceive(node.idString(), new NetworkReceive(node.idString(), buffer)));
}
use of org.apache.kafka.common.requests.ApiVersionsResponse in project apache-kafka-on-k8s by banzaicloud.
the class SaslAuthenticatorTest method sendVersionRequestReceiveResponse.
private ApiVersionsResponse sendVersionRequestReceiveResponse(String node) throws Exception {
ApiVersionsRequest handshakeRequest = createApiVersionsRequestV0();
ApiVersionsResponse response = (ApiVersionsResponse) sendKafkaRequestReceiveResponse(node, ApiKeys.API_VERSIONS, handshakeRequest);
assertEquals(Errors.NONE, response.error());
return response;
}
use of org.apache.kafka.common.requests.ApiVersionsResponse in project apache-kafka-on-k8s by banzaicloud.
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));
SaslChannelBuilder serverChannelBuilder = new SaslChannelBuilder(Mode.SERVER, jaasContexts, securityProtocol, listenerName, false, saslMechanism, true, credentialCache, null) {
@Override
protected SaslServerAuthenticator buildServerAuthenticator(Map<String, ?> configs, String id, TransportLayer transportLayer, Map<String, Subject> subjects) throws IOException {
return new SaslServerAuthenticator(configs, id, jaasContexts, subjects, null, credentialCache, listenerName, securityProtocol, transportLayer, null) {
@Override
protected ApiVersionsResponse apiVersionsResponse() {
List<ApiVersion> apiVersions = new ArrayList<>(ApiVersionsResponse.defaultApiVersionsResponse().apiVersions());
for (Iterator<ApiVersion> it = apiVersions.iterator(); it.hasNext(); ) {
ApiVersion apiVersion = it.next();
if (apiVersion.apiKey == ApiKeys.SASL_AUTHENTICATE.id) {
it.remove();
break;
}
}
return new ApiVersionsResponse(0, Errors.NONE, apiVersions);
}
@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);
server.start();
return server;
}
use of org.apache.kafka.common.requests.ApiVersionsResponse in project apache-kafka-on-k8s by banzaicloud.
the class SaslAuthenticatorTest method testUnauthenticatedApiVersionsRequest.
/**
* Tests that Kafka ApiVersionsRequests are handled by the SASL server authenticator
* prior to SASL handshake flow and that subsequent authentication succeeds
* when transport layer is PLAINTEXT/SSL. This test uses a non-SASL client that simulates
* SASL authentication after ApiVersionsRequest.
* <p>
* Test sequence (using <tt>securityProtocol=PLAINTEXT</tt> as an example):
* <ol>
* <li>Starts a SASL_PLAINTEXT test server that simply echoes back client requests after authentication.</li>
* <li>A (non-SASL) PLAINTEXT test client connects to the SASL server port. Client is now unauthenticated.<./li>
* <li>The unauthenticated non-SASL client sends an ApiVersionsRequest and validates the response.
* A valid response indicates that {@link SaslServerAuthenticator} of the test server responded to
* the ApiVersionsRequest even though the client is not yet authenticated.</li>
* <li>The unauthenticated non-SASL client sends a SaslHandshakeRequest and validates the response. A valid response
* indicates that {@link SaslServerAuthenticator} of the test server responded to the SaslHandshakeRequest
* after processing ApiVersionsRequest.</li>
* <li>The unauthenticated non-SASL client sends the SASL/PLAIN packet containing username/password to authenticate
* itself. The client is now authenticated by the server. At this point this test client is at the
* same state as a regular SASL_PLAINTEXT client that is <tt>ready</tt>.</li>
* <li>The authenticated client sends random data to the server and checks that the data is echoed
* back by the test server (ie, not Kafka request-response) to ensure that the client now
* behaves exactly as a regular SASL_PLAINTEXT client that has completed authentication.</li>
* </ol>
*/
private void testUnauthenticatedApiVersionsRequest(SecurityProtocol securityProtocol, short saslHandshakeVersion) throws Exception {
configureMechanisms("PLAIN", Arrays.asList("PLAIN"));
server = createEchoServer(securityProtocol);
// Create non-SASL connection to manually authenticate after ApiVersionsRequest
String node = "1";
SecurityProtocol clientProtocol;
switch(securityProtocol) {
case SASL_PLAINTEXT:
clientProtocol = SecurityProtocol.PLAINTEXT;
break;
case SASL_SSL:
clientProtocol = SecurityProtocol.SSL;
break;
default:
throw new IllegalArgumentException("Server protocol " + securityProtocol + " is not SASL");
}
createClientConnection(clientProtocol, node);
NetworkTestUtils.waitForChannelReady(selector, node);
// Send ApiVersionsRequest and check response
ApiVersionsResponse versionsResponse = sendVersionRequestReceiveResponse(node);
assertEquals(ApiKeys.SASL_HANDSHAKE.oldestVersion(), versionsResponse.apiVersion(ApiKeys.SASL_HANDSHAKE.id).minVersion);
assertEquals(ApiKeys.SASL_HANDSHAKE.latestVersion(), versionsResponse.apiVersion(ApiKeys.SASL_HANDSHAKE.id).maxVersion);
assertEquals(ApiKeys.SASL_AUTHENTICATE.oldestVersion(), versionsResponse.apiVersion(ApiKeys.SASL_AUTHENTICATE.id).minVersion);
assertEquals(ApiKeys.SASL_AUTHENTICATE.latestVersion(), versionsResponse.apiVersion(ApiKeys.SASL_AUTHENTICATE.id).maxVersion);
// Send SaslHandshakeRequest and check response
SaslHandshakeResponse handshakeResponse = sendHandshakeRequestReceiveResponse(node, saslHandshakeVersion);
assertEquals(Collections.singletonList("PLAIN"), handshakeResponse.enabledMechanisms());
// Complete manual authentication and check send/receive succeed
authenticateUsingSaslPlainAndCheckConnection(node, saslHandshakeVersion > 0);
}
Aggregations