org.codelibs.elasticsearch.auth.security.IndexAuthenticator Maven / Gradle / Ivy
package org.codelibs.elasticsearch.auth.security;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import java.util.Map;
import org.apache.commons.codec.digest.DigestUtils;
import org.codelibs.elasticsearch.auth.AuthException;
import org.codelibs.elasticsearch.auth.service.AuthService;
import org.codelibs.elasticsearch.auth.util.MapUtil;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.component.AbstractLifecycleComponent;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.logging.Loggers;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.rest.RestRequest;
import org.elasticsearch.rest.RestStatus;
public class IndexAuthenticator extends
AbstractLifecycleComponent implements Authenticator {
private static final ESLogger logger = Loggers
.getLogger(IndexAuthenticator.class);;
protected Client client;
protected AuthService authService;
protected String authIndex;
protected String userType;
protected String usernameKey;
protected String passwordKey;
@Inject
public IndexAuthenticator(final Settings settings, final Client client,
final AuthService authService) {
super(settings);
this.client = client;
this.authService = authService;
authIndex = settings.get("auth.authenticator.index.index", "auth");
userType = settings.get("auth.authenticator.index.type", "user");
usernameKey = settings.get("auth.authenticator.index.username",
"username");
passwordKey = settings.get("auth.authenticator.index.password",
"password");
}
@Override
protected void doStart() throws ElasticsearchException {
logger.info("Registering IndexAuthenticator.");
authService.registerAuthenticator("index", this);
}
@Override
protected void doStop() throws ElasticsearchException {
}
@Override
protected void doClose() throws ElasticsearchException {
}
@Override
public void login(final RestRequest request,
final ActionListener listener) {
String username = request.param(usernameKey);
String password = request.param(passwordKey);
final BytesReference content = request.content();
final XContentType xContentType = XContentFactory.xContentType(content);
XContentParser parser = null;
try {
parser = XContentFactory.xContent(xContentType).createParser(
content);
final XContentParser.Token t = parser.nextToken();
if (t != null) {
final Map contentMap = parser.map();
username = MapUtil.getAsString(contentMap, usernameKey,
username);
password = MapUtil.getAsString(contentMap, passwordKey,
password);
}
} catch (final Exception e) {
listener.onFailure(e);
return;
} finally {
if (parser != null) {
parser.close();
}
}
if (username == null) {
listener.onResponse(new String[0]);
return;
}
processLogin(username, password, listener);
}
private void processLogin(final String username, final String password,
final ActionListener listener) {
client.prepareGet(authIndex, userType, getUserId(username)).execute(
new ActionListener() {
@Override
public void onResponse(final GetResponse response) {
final Map sourceMap = response
.getSource();
if (sourceMap != null) {
final String hash = (String) sourceMap
.get("password");
if (hash != null
&& hash.equals(hashPassword(password))) {
if (logger.isDebugEnabled()) {
logger.debug(sourceMap.get("username")
+ " is logged in.");
}
listener.onResponse(MapUtil.getAsArray(
sourceMap, "roles", new String[0]));
return;
}
}
listener.onResponse(new String[0]);
return;
}
@Override
public void onFailure(final Throwable e) {
listener.onFailure(e);
}
});
}
@Override
public void createUser(final String username, final String password,
final String[] roles, final ActionListener listener) {
try {
final XContentBuilder builder = jsonBuilder() //
.startObject() //
.field("username", username) //
.field("password", hashPassword(password)) //
.field("roles", roles) //
.endObject();
client.prepareIndex(authIndex, userType, getUserId(username))
.setSource(builder).setRefresh(true)
.execute(new ActionListener() {
@Override
public void onResponse(final IndexResponse response) {
listener.onResponse(null);
}
@Override
public void onFailure(final Throwable e) {
listener.onFailure(new AuthException(
RestStatus.INTERNAL_SERVER_ERROR,
"Could not create " + username, e));
}
});
} catch (final Exception e) {
listener.onFailure(new AuthException(
RestStatus.INTERNAL_SERVER_ERROR, "Could not create "
+ username, e));
}
}
@Override
public void updateUser(final String username, final String password,
final String[] roles, final ActionListener listener) {
try {
final XContentBuilder builder = jsonBuilder().startObject()
.field("doc").startObject();
if (password != null) {
builder.field("password", hashPassword(password));
}
if (roles != null) {
builder.field("roles", roles);
}
builder.endObject().endObject();
final String userId = getUserId(username);
client.prepareUpdate(authIndex, userType, userId)
.setSource(builder).setRefresh(true)
.execute(new ActionListener() {
@Override
public void onResponse(final UpdateResponse response) {
if (!userId.equals(response.getId())) {
listener.onFailure(new AuthException(
RestStatus.BAD_REQUEST,
"Could not update " + username));
} else {
listener.onResponse(null);
}
}
@Override
public void onFailure(final Throwable e) {
listener.onFailure(new AuthException(
RestStatus.INTERNAL_SERVER_ERROR,
"Could not update " + username, e));
}
});
} catch (final Exception e) {
listener.onFailure(new AuthException(
RestStatus.INTERNAL_SERVER_ERROR, "Could not update "
+ username, e));
}
}
@Override
public void deleteUser(final String username,
final ActionListener listener) {
client.prepareDelete(authIndex, userType, getUserId(username))
.setRefresh(true).execute(new ActionListener() {
@Override
public void onResponse(final DeleteResponse response) {
if (response.isFound()) {
listener.onResponse(null);
} else {
listener.onFailure(new AuthException(
RestStatus.BAD_REQUEST, "Could not delete "
+ username));
}
}
@Override
public void onFailure(final Throwable e) {
listener.onFailure(new AuthException(
RestStatus.INTERNAL_SERVER_ERROR,
"Could not delete " + username, e));
}
});
}
protected String getUserId(final String username) {
return DigestUtils.sha512Hex(username);
}
protected String hashPassword(final String password) {
if (password == null) {
return "";
}
return DigestUtils.sha512Hex(password);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy