in src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java [496:621]
public void onIndexModule(IndexModule indexModule) {
//called for every index!
if (!disabled && !client && !SSLConfig.isSslOnlyMode()) {
log.debug("Handle auditLog {} for onIndexModule() of index {}", auditLog.getClass(), indexModule.getIndex().getName());
final ComplianceIndexingOperationListener ciol = new ComplianceIndexingOperationListenerImpl(auditLog);
indexModule.addIndexOperationListener(ciol);
indexModule.setReaderWrapper(indexService -> new SecurityFlsDlsIndexSearcherWrapper(indexService, settings, adminDns, cs, auditLog, ciol, evaluator, salt));
indexModule.forceQueryCacheProvider((indexSettings,nodeCache)->new QueryCache() {
@Override
public Index index() {
return indexSettings.getIndex();
}
@Override
public void close() throws OpenSearchException {
clear("close");
}
@Override
public void clear(String reason) {
nodeCache.clearIndex(index().getName());
}
@Override
public Weight doCache(Weight weight, QueryCachingPolicy policy) {
final Map<String, Set<String>> allowedFlsFields = (Map<String, Set<String>>) HeaderHelper.deserializeSafeFromHeader(threadPool.getThreadContext(),
ConfigConstants.OPENDISTRO_SECURITY_FLS_FIELDS_HEADER);
if(SecurityUtils.evalMap(allowedFlsFields, index().getName()) != null) {
return weight;
} else {
final Map<String, Set<String>> maskedFieldsMap = (Map<String, Set<String>>) HeaderHelper.deserializeSafeFromHeader(threadPool.getThreadContext(),
ConfigConstants.OPENDISTRO_SECURITY_MASKED_FIELD_HEADER);
if(SecurityUtils.evalMap(maskedFieldsMap, index().getName()) != null) {
return weight;
} else {
return nodeCache.doCache(weight, policy);
}
}
}
});
indexModule.addSearchOperationListener(new SearchOperationListener() {
@Override
public void onPreQueryPhase(SearchContext context) {
dlsFlsValve.handleSearchContext(context, threadPool, namedXContentRegistry);
}
@Override
public void onNewReaderContext(ReaderContext readerContext) {
final boolean interClusterRequest = HeaderHelper.isInterClusterRequest(threadPool.getThreadContext());
if (Origin.LOCAL.toString().equals(threadPool.getThreadContext().getTransient(ConfigConstants.OPENDISTRO_SECURITY_ORIGIN))
&& (interClusterRequest || HeaderHelper.isDirectRequest(threadPool.getThreadContext()))
) {
readerContext.putInContext("_opendistro_security_scroll_auth_local", Boolean.TRUE);
} else {
readerContext.putInContext("_opendistro_security_scroll_auth", threadPool.getThreadContext()
.getTransient(ConfigConstants.OPENDISTRO_SECURITY_USER));
}
}
@Override
public void onNewScrollContext(ReaderContext readerContext) {
final boolean interClusterRequest = HeaderHelper.isInterClusterRequest(threadPool.getThreadContext());
if (Origin.LOCAL.toString().equals(threadPool.getThreadContext().getTransient(ConfigConstants.OPENDISTRO_SECURITY_ORIGIN))
&& (interClusterRequest || HeaderHelper.isDirectRequest(threadPool.getThreadContext()))
) {
readerContext.putInContext("_opendistro_security_scroll_auth_local", Boolean.TRUE);
} else {
readerContext.putInContext("_opendistro_security_scroll_auth", threadPool.getThreadContext()
.getTransient(ConfigConstants.OPENDISTRO_SECURITY_USER));
}
}
@Override
public void validateReaderContext(ReaderContext readerContext, TransportRequest transportRequest) {
if (transportRequest instanceof InternalScrollSearchRequest) {
final Object _isLocal = readerContext.getFromContext("_opendistro_security_scroll_auth_local");
final Object _user = readerContext.getFromContext("_opendistro_security_scroll_auth");
if (_user != null && (_user instanceof User)) {
final User scrollUser = (User) _user;
final User currentUser = threadPool.getThreadContext()
.getTransient(ConfigConstants.OPENDISTRO_SECURITY_USER);
if (!scrollUser.equals(currentUser)) {
auditLog.logMissingPrivileges(SearchScrollAction.NAME, transportRequest, null);
log.error("Wrong user {} in reader context, expected {}", scrollUser, currentUser);
throw new OpenSearchSecurityException("Wrong user in reader context", RestStatus.FORBIDDEN);
}
} else if (_isLocal != Boolean.TRUE) {
auditLog.logMissingPrivileges(SearchScrollAction.NAME, transportRequest, null);
throw new OpenSearchSecurityException("No user in reader context", RestStatus.FORBIDDEN);
}
}
}
@Override
public void onQueryPhase(SearchContext searchContext, long tookInNanos) {
QuerySearchResult queryResult = searchContext.queryResult();
assert queryResult != null;
if (!queryResult.hasAggs()) {
return;
}
final Map<String, Set<String>> maskedFieldsMap = (Map<String, Set<String>>) HeaderHelper.deserializeSafeFromHeader(threadPool.getThreadContext(),
ConfigConstants.OPENDISTRO_SECURITY_MASKED_FIELD_HEADER);
final String maskedEval = SecurityUtils.evalMap(maskedFieldsMap, indexModule.getIndex().getName());
if (maskedEval != null) {
final Set<String> mf = maskedFieldsMap.get(maskedEval);
if (mf != null && !mf.isEmpty()) {
dlsFlsValve.onQueryPhase(queryResult);
}
}
}
});
}
}