All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.hazelcast.client.impl.protocol.task.AuthenticationBaseMessageTask Maven / Gradle / Ivy

/*
 * Copyright (c) 2008-2016, Hazelcast, Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.hazelcast.client.impl.protocol.task;

import com.hazelcast.client.ClientEndpoint;
import com.hazelcast.client.ClientTypes;
import com.hazelcast.client.impl.ClientEndpointImpl;
import com.hazelcast.client.impl.client.ClientPrincipal;
import com.hazelcast.client.impl.operations.ClientReAuthOperation;
import com.hazelcast.client.impl.protocol.AuthenticationStatus;
import com.hazelcast.client.impl.protocol.ClientMessage;
import com.hazelcast.config.GroupConfig;
import com.hazelcast.core.Member;
import com.hazelcast.instance.Node;
import com.hazelcast.logging.ILogger;
import com.hazelcast.nio.Address;
import com.hazelcast.nio.Connection;
import com.hazelcast.nio.ConnectionType;
import com.hazelcast.security.Credentials;
import com.hazelcast.security.SecurityContext;
import com.hazelcast.security.UsernamePasswordCredentials;
import com.hazelcast.util.UuidUtil;

import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
import java.security.Permission;
import java.util.Collection;
import java.util.Set;
import java.util.logging.Level;

/**
 * Base authentication task
 */
public abstract class AuthenticationBaseMessageTask

extends AbstractCallableMessageTask

{ protected transient ClientPrincipal principal; protected transient Credentials credentials; protected transient byte clientSerializationVersion; public AuthenticationBaseMessageTask(ClientMessage clientMessage, Node node, Connection connection) { super(clientMessage, node, connection); } @Override protected ClientEndpointImpl getEndpoint() { if (connection.isAlive()) { return new ClientEndpointImpl(clientEngine, connection); } else { handleEndpointNotCreatedConnectionNotAlive(); } return null; } @Override protected boolean isAuthenticationMessage() { return true; } private void handleEndpointNotCreatedConnectionNotAlive() { logger.warning("Dropped: " + clientMessage + " -> endpoint not created for AuthenticationRequest, connection not alive"); } @Override public Object call() { byte serializationServiceVersion = serializationService.getVersion(); AuthenticationStatus authenticationStatus; if (clientSerializationVersion != serializationServiceVersion) { authenticationStatus = AuthenticationStatus.SERIALIZATION_VERSION_MISMATCH; } else { authenticationStatus = authenticate(); } switch (authenticationStatus) { case AUTHENTICATED: return handleAuthenticated(); case CREDENTIALS_FAILED: return handleUnauthenticated(); case SERIALIZATION_VERSION_MISMATCH: return handleSerializationVersionMismatch(); default: throw new IllegalStateException("Unsupported authentication status :" + authenticationStatus); } } private AuthenticationStatus authenticate() { ILogger logger = clientEngine.getLogger(getClass()); AuthenticationStatus status; if (credentials == null) { status = AuthenticationStatus.CREDENTIALS_FAILED; logger.severe("Could not retrieve Credentials object!"); } else if (clientEngine.getSecurityContext() != null) { status = authenticate(clientEngine.getSecurityContext()); } else if (credentials instanceof UsernamePasswordCredentials) { UsernamePasswordCredentials usernamePasswordCredentials = (UsernamePasswordCredentials) credentials; status = authenticate(usernamePasswordCredentials); } else { status = AuthenticationStatus.CREDENTIALS_FAILED; logger.severe("Hazelcast security is disabled.\nUsernamePasswordCredentials or cluster " + "group-name and group-password should be used for authentication!\n" + "Current credentials type is: " + credentials.getClass().getName()); } return status; } private AuthenticationStatus authenticate(SecurityContext securityContext) { Connection connection = endpoint.getConnection(); credentials.setEndpoint(connection.getInetAddress().getHostAddress()); try { LoginContext lc = securityContext.createClientLoginContext(credentials); lc.login(); endpoint.setLoginContext(lc); return AuthenticationStatus.AUTHENTICATED; } catch (LoginException e) { logger.warning(e); return AuthenticationStatus.CREDENTIALS_FAILED; } } private AuthenticationStatus authenticate(UsernamePasswordCredentials credentials) { GroupConfig groupConfig = nodeEngine.getConfig().getGroupConfig(); String nodeGroupName = groupConfig.getName(); String nodeGroupPassword = groupConfig.getPassword(); boolean usernameMatch = nodeGroupName.equals(credentials.getUsername()); boolean passwordMatch = nodeGroupPassword.equals(credentials.getPassword()); return usernameMatch && passwordMatch ? AuthenticationStatus.AUTHENTICATED : AuthenticationStatus.CREDENTIALS_FAILED; } private Object handleUnauthenticated() { Connection connection = endpoint.getConnection(); ILogger logger = clientEngine.getLogger(getClass()); logger.log(Level.WARNING, "Received auth from " + connection + " with principal " + principal + " , authentication failed"); byte status = AuthenticationStatus.CREDENTIALS_FAILED.getId(); return encodeAuth(status, null, null, null, serializationService.getVersion()); } private Object handleSerializationVersionMismatch() { return encodeAuth(AuthenticationStatus.SERIALIZATION_VERSION_MISMATCH.getId(), null, null, null, serializationService.getVersion()); } private ClientMessage handleAuthenticated() { if (isOwnerConnection()) { final String uuid = getUuid(); final String localMemberUUID = clientEngine.getLocalMember().getUuid(); principal = new ClientPrincipal(uuid, localMemberUUID); reAuthLocal(); Collection members = nodeEngine.getClusterService().getMembers(); for (Member member : members) { if (!member.localMember()) { ClientReAuthOperation op = new ClientReAuthOperation(uuid); op.setCallerUuid(localMemberUUID); nodeEngine.getOperationService().send(op, member.getAddress()); } } } boolean isNotMember = clientEngine.getClusterService().getMember(principal.getOwnerUuid()) == null; if (isNotMember) { byte status = AuthenticationStatus.CREDENTIALS_FAILED.getId(); return encodeAuth(status, null, null, null, serializationService.getVersion()); } Connection connection = endpoint.getConnection(); ILogger logger = clientEngine.getLogger(getClass()); endpoint.authenticated(principal, credentials, isOwnerConnection()); setConnectionType(); logger.log(Level.INFO, "Received auth from " + connection + ", successfully authenticated" + ", principal : " + principal + ", owner connection : " + isOwnerConnection()); endpointManager.registerEndpoint(endpoint); clientEngine.bind(endpoint); final Address thisAddress = clientEngine.getThisAddress(); byte status = AuthenticationStatus.AUTHENTICATED.getId(); return encodeAuth(status, thisAddress, principal.getUuid(), principal.getOwnerUuid(), serializationService.getVersion()); } private void setConnectionType() { String type = getClientType(); if (ClientTypes.JAVA.equals(type)) { connection.setType(ConnectionType.JAVA_CLIENT); } else if (ClientTypes.CSHARP.equals(type)) { connection.setType(ConnectionType.CSHARP_CLIENT); } else if (ClientTypes.CPP.equals(type)) { connection.setType(ConnectionType.CPP_CLIENT); } else if (ClientTypes.PYTHON.equals(type)) { connection.setType(ConnectionType.PYTHON_CLIENT); } else if (ClientTypes.RUBY.equals(type)) { connection.setType(ConnectionType.RUBY_CLIENT); } else { clientEngine.getLogger(getClass()).info("Unknown client type: " + type); connection.setType(ConnectionType.BINARY_CLIENT); } } protected abstract ClientMessage encodeAuth(byte status, Address thisAddress, String uuid, String ownerUuid, byte serializationVersion); protected abstract boolean isOwnerConnection(); protected abstract String getClientType(); private String getUuid() { if (principal != null) { return principal.getUuid(); } return UuidUtil.createClientUuid(endpoint.getConnection().getEndPoint()); } private void reAuthLocal() { final Set endpoints = endpointManager.getEndpoints(principal.getUuid()); for (ClientEndpoint endpoint : endpoints) { endpoint.authenticated(principal); } clientEngine.addOwnershipMapping(principal.getUuid(), principal.getOwnerUuid()); } @Override public Permission getRequiredPermission() { return null; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy