in src/main/java/org/opensearch/security/auth/BackendRegistry.java [354:553]
public boolean authenticate(final RestRequest request, final RestChannel channel, final ThreadContext threadContext) {
final boolean isDebugEnabled = log.isDebugEnabled();
if (request.getHttpChannel().getRemoteAddress() instanceof InetSocketAddress && isBlocked(((InetSocketAddress) request.getHttpChannel().getRemoteAddress()).getAddress())) {
if (isDebugEnabled) {
log.debug("Rejecting REST request because of blocked address: {}", request.getHttpChannel().getRemoteAddress());
}
channel.sendResponse(new BytesRestResponse(RestStatus.UNAUTHORIZED, "Authentication finally failed"));
return false;
}
final String sslPrincipal = (String) threadPool.getThreadContext().getTransient(ConfigConstants.OPENDISTRO_SECURITY_SSL_PRINCIPAL);
if(adminDns.isAdminDN(sslPrincipal)) {
//PKI authenticated REST call
threadPool.getThreadContext().putTransient(ConfigConstants.OPENDISTRO_SECURITY_USER, new User(sslPrincipal));
auditLog.logSucceededLogin(sslPrincipal, true, null, request);
return true;
}
if (userInjector.injectUser(request)) {
// ThreadContext injected user
return true;
}
if (!isInitialized()) {
log.error("Not yet initialized (you may need to run securityadmin)");
channel.sendResponse(new BytesRestResponse(RestStatus.SERVICE_UNAVAILABLE,
"OpenSearch Security not initialized."));
return false;
}
final TransportAddress remoteAddress = xffResolver.resolve(request);
final boolean isTraceEnabled = log.isTraceEnabled();
if (isTraceEnabled) {
log.trace("Rest authentication request from {} [original: {}]", remoteAddress, request.getHttpChannel().getRemoteAddress());
}
threadContext.putTransient(ConfigConstants.OPENDISTRO_SECURITY_REMOTE_ADDRESS, remoteAddress);
boolean authenticated = false;
User authenticatedUser = null;
AuthCredentials authCredenetials = null;
HTTPAuthenticator firstChallengingHttpAuthenticator = null;
//loop over all http/rest auth domains
for (final AuthDomain authDomain: restAuthDomains) {
if (isDebugEnabled) {
log.debug("Check authdomain for rest {}/{} or {} in total", authDomain.getBackend().getType(), authDomain.getOrder(), restAuthDomains.size());
}
final HTTPAuthenticator httpAuthenticator = authDomain.getHttpAuthenticator();
if(authDomain.isChallenge() && firstChallengingHttpAuthenticator == null) {
firstChallengingHttpAuthenticator = httpAuthenticator;
}
if (isTraceEnabled) {
log.trace("Try to extract auth creds from {} http authenticator", httpAuthenticator.getType());
}
final AuthCredentials ac;
try {
ac = httpAuthenticator.extractCredentials(request, threadContext);
} catch (Exception e1) {
if (isDebugEnabled) {
log.debug("'{}' extracting credentials from {} http authenticator", e1.toString(), httpAuthenticator.getType(), e1);
}
continue;
}
if (ac != null && isBlocked(authDomain.getBackend().getClass().getName(), ac.getUsername())) {
if (isDebugEnabled) {
log.debug("Rejecting REST request because of blocked user: {}, authDomain: {}", ac.getUsername(), authDomain);
}
continue;
}
authCredenetials = ac;
if (ac == null) {
//no credentials found in request
if(anonymousAuthEnabled) {
continue;
}
if(authDomain.isChallenge() && httpAuthenticator.reRequestAuthentication(channel, null)) {
auditLog.logFailedLogin("<NONE>", false, null, request);
log.trace("No 'Authorization' header, send 401 and 'WWW-Authenticate Basic'");
return false;
} else {
//no reRequest possible
if (isTraceEnabled) {
log.trace("No 'Authorization' header, send 403");
}
continue;
}
} else {
org.apache.logging.log4j.ThreadContext.put("user", ac.getUsername());
if (!ac.isComplete()) {
//credentials found in request but we need another client challenge
if(httpAuthenticator.reRequestAuthentication(channel, ac)) {
//auditLog.logFailedLogin(ac.getUsername()+" <incomplete>", request); --noauditlog
return false;
} else {
//no reRequest possible
continue;
}
}
}
//http completed
authenticatedUser = authcz(userCache, restRoleCache, ac, authDomain.getBackend(), restAuthorizers);
if(authenticatedUser == null) {
if (isDebugEnabled) {
log.debug("Cannot authenticate rest user {} (or add roles) with authdomain {}/{} of {}, try next", ac.getUsername(), authDomain.getBackend().getType(), authDomain.getOrder(), restAuthDomains);
}
for (AuthFailureListener authFailureListener : this.authBackendFailureListeners.get(authDomain.getBackend().getClass().getName())) {
authFailureListener.onAuthFailure(
(request.getHttpChannel().getRemoteAddress() instanceof InetSocketAddress) ? ((InetSocketAddress) request.getHttpChannel().getRemoteAddress()).getAddress()
: null,
ac, request);
}
continue;
}
if(adminDns.isAdmin(authenticatedUser)) {
log.error("Cannot authenticate rest user because admin user is not permitted to login via HTTP");
auditLog.logFailedLogin(authenticatedUser.getName(), true, null, request);
channel.sendResponse(new BytesRestResponse(RestStatus.FORBIDDEN,
"Cannot authenticate user because admin user is not permitted to login via HTTP"));
return false;
}
final String tenant = Utils.coalesce(request.header("securitytenant"), request.header("security_tenant"));
if (isDebugEnabled) {
log.debug("Rest user '{}' is authenticated", authenticatedUser);
log.debug("securitytenant '{}'", tenant);
}
authenticatedUser.setRequestedTenant(tenant);
authenticated = true;
break;
}//end looping auth domains
if(authenticated) {
final User impersonatedUser = impersonate(request, authenticatedUser);
threadContext.putTransient(ConfigConstants.OPENDISTRO_SECURITY_USER, impersonatedUser==null?authenticatedUser:impersonatedUser);
auditLog.logSucceededLogin((impersonatedUser == null ? authenticatedUser : impersonatedUser).getName(), false,
authenticatedUser.getName(), request);
} else {
if (isDebugEnabled) {
log.debug("User still not authenticated after checking {} auth domains", restAuthDomains.size());
}
if(authCredenetials == null && anonymousAuthEnabled) {
threadContext.putTransient(ConfigConstants.OPENDISTRO_SECURITY_USER, User.ANONYMOUS);
auditLog.logSucceededLogin(User.ANONYMOUS.getName(), false, null, request);
if (isDebugEnabled) {
log.debug("Anonymous User is authenticated");
}
return true;
}
if(firstChallengingHttpAuthenticator != null) {
if (isDebugEnabled) {
log.debug("Rerequest with {}", firstChallengingHttpAuthenticator.getClass());
}
if(firstChallengingHttpAuthenticator.reRequestAuthentication(channel, null)) {
if (isDebugEnabled) {
log.debug("Rerequest {} failed", firstChallengingHttpAuthenticator.getClass());
}
log.warn("Authentication finally failed for {} from {}", authCredenetials == null ? null:authCredenetials.getUsername(), remoteAddress);
auditLog.logFailedLogin(authCredenetials == null ? null:authCredenetials.getUsername(), false, null, request);
return false;
}
}
log.warn("Authentication finally failed for {} from {}", authCredenetials == null ? null : authCredenetials.getUsername(),
remoteAddress);
auditLog.logFailedLogin(authCredenetials == null ? null:authCredenetials.getUsername(), false, null, request);
notifyIpAuthFailureListeners(request, authCredenetials);
channel.sendResponse(new BytesRestResponse(RestStatus.UNAUTHORIZED, "Authentication finally failed"));
return false;
}
return authenticated;
}