use of org.apache.pulsar.common.api.AuthData in project pulsar by yahoo.
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 yahoo.
the class ClientCnx method newConnectCommand.
protected ByteBuf newConnectCommand() throws Exception {
// mutual authentication is to auth between `remoteHostName` and this client for this channel.
// each channel will have a mutual client/server pair, mutual client evaluateChallenge with init data,
// and return authData to server.
authenticationDataProvider = authentication.getAuthData(remoteHostName);
AuthData authData = authenticationDataProvider.authenticate(AuthData.INIT_AUTH_DATA);
return Commands.newConnect(authentication.getAuthMethodName(), authData, this.protocolVersion, PulsarVersion.getVersion(), proxyToTargetBrokerAddress, null, null, null);
}
use of org.apache.pulsar.common.api.AuthData in project pulsar by yahoo.
the class ProxyConnection method handleAuthResponse.
@Override
protected void handleAuthResponse(CommandAuthResponse authResponse) {
checkArgument(state == State.Connecting);
checkArgument(authResponse.hasResponse());
checkArgument(authResponse.getResponse().hasAuthData() && authResponse.getResponse().hasAuthMethodName());
if (LOG.isDebugEnabled()) {
LOG.debug("Received AuthResponse from {}, auth method: {}", remoteAddress, authResponse.getResponse().getAuthMethodName());
}
try {
AuthData clientData = AuthData.of(authResponse.getResponse().getAuthData());
doAuthentication(clientData);
} catch (Exception e) {
String msg = "Unable to handleAuthResponse";
LOG.warn("[{}] {} ", remoteAddress, msg, e);
ctx.writeAndFlush(Commands.newError(-1, ServerError.AuthenticationError, msg)).addListener(ChannelFutureListener.CLOSE);
}
}
use of org.apache.pulsar.common.api.AuthData in project pulsar by yahoo.
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();
}
use of org.apache.pulsar.common.api.AuthData in project pulsar by yahoo.
the class AuthenticationSasl method newRequestHeader.
// set header according to previous response
@Override
public Set<Entry<String, String>> newRequestHeader(String hostName, AuthenticationDataProvider authData, Map<String, String> previousRespHeaders) throws Exception {
Map<String, String> headers = new HashMap<>();
if (authData.hasDataForHttp()) {
authData.getHttpHeaders().forEach(header -> headers.put(header.getKey(), header.getValue()));
}
// role token expired in last check. remove role token, new sasl client, restart auth.
if (isRoleTokenExpired(previousRespHeaders)) {
previousRespHeaders = null;
saslRoleToken = null;
authData = getAuthData(hostName);
}
// 3. server checked, and not return SASL_STATE_COMPLETE
if (saslRoleToken != null) {
headers.put(SASL_AUTH_ROLE_TOKEN, saslRoleToken);
if (previousRespHeaders == null) {
// first time auth, ask server to check the role token expired or not.
if (log.isDebugEnabled()) {
log.debug("request builder add token: Check token");
}
headers.put(SASL_HEADER_STATE, SASL_STATE_SERVER_CHECK_TOKEN);
} else if (previousRespHeaders.get(SASL_HEADER_STATE).equalsIgnoreCase(SASL_STATE_COMPLETE)) {
headers.put(SASL_HEADER_STATE, SASL_STATE_COMPLETE);
if (log.isDebugEnabled()) {
log.debug("request builder add token. role verified by server");
}
} else {
if (log.isDebugEnabled()) {
log.debug("request builder add token. NOT complete. state: {}", previousRespHeaders.get(SASL_HEADER_STATE));
}
headers.put(SASL_HEADER_STATE, SASL_STATE_NEGOTIATE);
}
return headers.entrySet();
}
// role token is null, need do auth.
if (previousRespHeaders == null) {
if (log.isDebugEnabled()) {
log.debug("Init authn in client side");
}
// first time init
headers.put(SASL_HEADER_STATE, SASL_STATE_CLIENT_INIT);
AuthData initData = authData.authenticate(AuthData.INIT_AUTH_DATA);
headers.put(SASL_AUTH_TOKEN, Base64.getEncoder().encodeToString(initData.getBytes()));
} else {
AuthData brokerData = AuthData.of(Base64.getDecoder().decode(previousRespHeaders.get(SASL_AUTH_TOKEN)));
AuthData clientData = authData.authenticate(brokerData);
headers.put(SASL_STATE_SERVER, previousRespHeaders.get(SASL_STATE_SERVER));
headers.put(SASL_HEADER_TYPE, SASL_TYPE_VALUE);
headers.put(SASL_HEADER_STATE, SASL_STATE_NEGOTIATE);
headers.put(SASL_AUTH_TOKEN, Base64.getEncoder().encodeToString(clientData.getBytes()));
}
return headers.entrySet();
}
Aggregations