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);
}
}
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();
}
}
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);
}
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();
}
}));
}
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();
}
Aggregations