/* The contents of this file are subject to the license and copyright terms
* detailed in the license directory at the root of the source tree (also
* available online at http://fedora-commons.org/license/).
*/
package org.fcrepo.server.security.servletfilters.ldap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Map;
import java.util.Set;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.servlet.FilterConfig;
import org.fcrepo.server.errors.authorization.PasswordComparisonException;
import org.fcrepo.server.security.servletfilters.BaseCaching;
import org.fcrepo.server.security.servletfilters.CacheElement;
import org.fcrepo.server.security.servletfilters.FilterSetup;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Bill Niebel
* @deprecated
*/
@Deprecated
public class FilterLdap
extends BaseCaching {
private static final String[] EMPTY_STRING_ARRAY = new String[0];
public static final String CONTEXT_VERSION_KEY = "java.naming.ldap.version";
public static final String VERSION_KEY = "version";
public static final String BIND_FILTER_KEY = "bind-filter";
public static final String URL_KEY = "url";
public static final String BASE_KEY = "search-base";
public static final String FILTER_KEY = "search-filter";
public static final String USERID_KEY = "id-attribute";
public static final String PASSWORD_KEY = "password-attribute";
public static final String ATTRIBUTES2RETURN_KEY = "attributes";
public static final String GROUPS_NAME_KEY = "attributes-common-name";
public static final String SECURITY_AUTHENTICATION_KEY =
"security-authentication";
public static final String SECURITY_PRINCIPAL_KEY = "security-principal";
public static final String SECURITY_CREDENTIALS_KEY =
"security-credentials";
private static final Logger logger =
LoggerFactory.getLogger(FilterLdap.class);
private String[] DIRECTORY_ATTRIBUTES_NEEDED = null;
private String VERSION = "2";
private String BIND_FILTER = "";
private String URL = "";
private String BASE = "";
private String FILTER = "";
private String PASSWORD = "";
private String[] ATTRIBUTES2RETURN = null;
private String GROUPS_NAME = null;
public String SECURITY_AUTHENTICATION = "none";
public String SECURITY_PRINCIPAL = null;
public String SECURITY_CREDENTIALS = null;
//public Boolean REQUIRE_RETURNED_ATTRS = Boolean.FALSE;
@Override
public void init(FilterConfig filterConfig) {
String m = "L init() ";
try {
logger.debug(m + ">");
super.init(filterConfig);
m = FilterSetup.getFilterNameAbbrev(FILTER_NAME) + " init() ";
inited = false;
if (!initErrors) {
Set<String> temp = new HashSet<String>();
if (ATTRIBUTES2RETURN == null) {
ATTRIBUTES2RETURN = EMPTY_STRING_ARRAY;
} else {
for (String element : ATTRIBUTES2RETURN) {
temp.add(element);
}
}
if (AUTHENTICATE && PASSWORD != null && !PASSWORD.isEmpty()) {
temp.add(PASSWORD);
}
DIRECTORY_ATTRIBUTES_NEEDED =
(String[]) temp.toArray(StringArrayPrototype);
boolean haveBindMethod = false;
if (SECURITY_AUTHENTICATION != null
&& !SECURITY_AUTHENTICATION.isEmpty()) {
haveBindMethod = true;
}
boolean haveSuperUser = false;
if (SECURITY_PRINCIPAL != null
&& !SECURITY_PRINCIPAL.isEmpty()) {
haveSuperUser = true;
}
boolean haveSuperUserPassword = false;
if (SECURITY_CREDENTIALS != null
&& !SECURITY_CREDENTIALS.isEmpty()) {
haveSuperUserPassword = true;
}
if (haveBindMethod && haveSuperUserPassword) {
initErrors = !haveSuperUser;
}
}
if (initErrors) {
logger.error(m + "not initialized; see previous error");
}
inited = true;
} finally {
logger.debug("{}<", m);
}
}
@Override
public void destroy() {
String m = FilterSetup.getFilterNameAbbrev(FILTER_NAME) + " destroy() ";
try {
logger.debug("{}>", m);
super.destroy();
} finally {
logger.debug("{}<", m);
}
}
@Override
protected void initThisSubclass(String key, String value) {
String m =
FilterSetup.getFilterNameAbbrev(FILTER_NAME)
+ " initThisSubclass() ";
try {
logger.debug("{}>", m);
logger.debug("{}{}=={}", m, key, value);
boolean setLocally = false;
if (VERSION_KEY.equals(key)) {
VERSION = value;
setLocally = true;
} else if (BIND_FILTER_KEY.equals(key)) {
BIND_FILTER = value;
setLocally = true;
} else if (URL_KEY.equals(key)) {
URL = value;
setLocally = true;
} else if (BASE_KEY.equals(key)) {
BASE = value;
setLocally = true;
} else if (USERID_KEY.equals(key)) {
setLocally = true;
} else if (ATTRIBUTES2RETURN_KEY.equals(key)) {
if (value.indexOf(",") < 0) {
if (value.isEmpty()) {
ATTRIBUTES2RETURN = null;
} else {
ATTRIBUTES2RETURN = new String[1];
ATTRIBUTES2RETURN[0] = value;
}
} else {
ATTRIBUTES2RETURN = value.split(",");
}
setLocally = true;
} else if (GROUPS_NAME_KEY.equals(key)) {
GROUPS_NAME = value;
setLocally = true;
} else if (FILTER_KEY.equals(key)) {
FILTER = value;
setLocally = true;
} else if (PASSWORD_KEY.equals(key)) {
PASSWORD = value;
setLocally = true;
} else if (SECURITY_AUTHENTICATION_KEY.equals(key)) {
SECURITY_AUTHENTICATION = value;
setLocally = true;
} else if (SECURITY_PRINCIPAL_KEY.equals(key)) {
SECURITY_PRINCIPAL = value;
setLocally = true;
} else if (SECURITY_CREDENTIALS_KEY.equals(key)) {
SECURITY_CREDENTIALS = value;
setLocally = true;
/*
* } else if (REQUIRE_RETURNED_ATTRS_KEY.equals(key)) {
* REQUIRE_RETURNED_ATTRS = Boolean.valueOf(value); setLocally =
* true;
*/
} else {
logger.debug("{}deferring to super", m);
super.initThisSubclass(key, value);
}
if (setLocally) {
logger.info("{}known parameter {}=={}", m, key, value);
}
} finally {
logger.debug("{}<", m);
}
}
private final String applyFilter(String filter, String[] args) {
String m =
FilterSetup.getFilterNameAbbrev(FILTER_NAME)
+ " applyFilter() ";
String result = filter;
logger.debug("{}result=={}", m, result);
int i = args.length - 1;
for (; i >= 0; i--) {
String regex = "\\{" + Integer.toString(i) + "\\}";
logger.debug("{}regex =={}", m, regex);
logger.debug("{}arg =={}", m, args[i]);
result = result.replaceFirst(regex, args[i]);
logger.debug("{}result=={}", m, result);
}
return result;
}
private boolean bindRequired() {
boolean bindRequired = "simple".equals(SECURITY_AUTHENTICATION);
return bindRequired;
}
private boolean individualUserBind() {
boolean individualUserBind =
bindRequired() && AUTHENTICATE
&& (PASSWORD == null || PASSWORD.isEmpty());
return individualUserBind;
}
private boolean individualUserComparison() {
boolean individualUserComparison =
AUTHENTICATE && PASSWORD != null && !PASSWORD.isEmpty();
return individualUserComparison;
}
private Hashtable<String, String> getEnvironment(String userid, String password) {
String m =
FilterSetup.getFilterNameAbbrev(FILTER_NAME)
+ " getEnvironment() ";
Hashtable<String, String> env = null;
try {
env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory");
if (VERSION != null && !VERSION.isEmpty()) {
logger.debug("{}ldap explicit version=={}", m, VERSION);
env.put(CONTEXT_VERSION_KEY, VERSION);
}
logger.debug("ldap version==", m, env.get(CONTEXT_VERSION_KEY));
env.put(Context.PROVIDER_URL, URL);
logger.debug("{}ldap url=={}", m, env.get(Context.PROVIDER_URL));
if (!bindRequired()) {
logger.debug("{}\"binding\" anonymously", m);
} else {
env.put(Context.SECURITY_AUTHENTICATION,
SECURITY_AUTHENTICATION);
String userForBind = null;
String passwordForBind = null;
if (!individualUserBind()) {
userForBind = SECURITY_PRINCIPAL;
passwordForBind = SECURITY_CREDENTIALS;
logger.debug("{}binding to protected directory", m);
} else {
passwordForBind = password;
if (SECURITY_PRINCIPAL == null
|| SECURITY_PRINCIPAL.isEmpty()) {
userForBind = userid;
logger.debug("{}binding for real user", m);
} else {
//simulate test against user-bind at directory server
userForBind = SECURITY_PRINCIPAL;
logger.debug("{}binding for --test-- user", m);
}
}
env.put(Context.SECURITY_CREDENTIALS, passwordForBind);
String[] parms = {userForBind};
String userFormattedForBind = applyFilter(BIND_FILTER, parms);
env.put(Context.SECURITY_PRINCIPAL, userFormattedForBind);
}
logger.debug("{}bind w {}", m, env.get(Context.SECURITY_AUTHENTICATION));
logger.debug("{}user== {}", m, env.get(Context.SECURITY_PRINCIPAL));
logger.debug("{}passwd=={}", m, env.get(Context.SECURITY_CREDENTIALS));
} catch (Throwable th) {
if (LOG_STACK_TRACES) {
logger.error(m + "couldn't set up env for DirContext", th);
} else {
logger.error(m + "couldn't set up env for DirContext"
+ th.getMessage());
}
} finally {
logger.debug("{}< {}", m, env);
}
return env;
}
private final String getFilter(String userid) {
String m =
FilterSetup.getFilterNameAbbrev(FILTER_NAME) + " getFilter() ";
logger.debug("{}>", m);
String filter = null;
try {
filter = new String(FILTER);
filter = filter.replaceFirst("\\{0}", userid);
} catch (Throwable th) {
if (LOG_STACK_TRACES) {
logger.error(m + "couldn't set up filter for dir search", th);
} else {
logger.error(m + "couldn't set up filter for dir search"
+ th.getMessage());
}
} finally {
logger.debug("{}< {}", m, filter);
}
return filter;
}
private final SearchControls getSearchControls() {
String m =
FilterSetup.getFilterNameAbbrev(FILTER_NAME)
+ " getSearchControls() ";
logger.debug("{}>", m);
SearchControls searchControls = null;
try {
int nEntries2return = 0;
int millisecondTimeLimit = 0;
boolean retobj = true;
boolean deref = true;
searchControls =
new SearchControls(SearchControls.SUBTREE_SCOPE,
nEntries2return,
millisecondTimeLimit,
DIRECTORY_ATTRIBUTES_NEEDED,
retobj,
deref);
} catch (Throwable th) {
if (LOG_STACK_TRACES) {
logger.error(m + "couldn't set up search controls for dir search",
th);
} else {
logger.error(m + "couldn't set up search controls for dir search"
+ th.getMessage());
}
} finally {
logger.debug("{}< {}", m, searchControls);
}
return searchControls;
}
private NamingEnumeration<SearchResult> getBasicNamingEnumeration(String userid,
String password,
String filter,
SearchControls searchControls,
Hashtable<String, String> env)
throws NamingException, Exception {
String m =
FilterSetup.getFilterNameAbbrev(FILTER_NAME)
+ " getNamingEnumeration() ";
logger.debug("{}>", m);
NamingEnumeration<SearchResult> ne = null;
try {
DirContext ctx;
try {
ctx = new InitialDirContext(env);
} catch (NamingException th) {
String msg = "exception getting ldap context";
if (LOG_STACK_TRACES) {
logger.error(m + msg, th);
} else {
logger.error(m + msg + " " + th.getMessage());
}
throw th;
}
try {
ne = ctx.search(BASE, filter, searchControls);
} catch (NamingException th) {
String msg = "exception getting ldap enumeration";
if (LOG_STACK_TRACES) {
logger.error(m + msg, th);
} else {
logger.error(m + msg + " " + th.getMessage());
}
throw th;
}
if (ne == null) {
logger.error(m + "unexpected null ldap enumeration");
throw new NamingException("");
}
} finally {
logger.debug("{}< {}", m, ne);
}
return ne;
}
private NamingEnumeration<SearchResult> getNamingEnumeration(String userid,
String password,
String filter,
SearchControls searchControls,
Hashtable<String, String> env)
throws NamingException, Exception {
String m =
FilterSetup.getFilterNameAbbrev(FILTER_NAME)
+ " getNamingEnumeration() ";
logger.debug("{}>", m);
// this condition is to -further- protect against behavior suggested by
// log from hull (see below for first-line protection)
// the idea here is to steer clear of possible trouble in underlying
// code and avoid calling ldap w/o a needed and practical password
String msg = "[LDAP: error code 49 - Bind failed: ";
if (!individualUserBind()) {
logger.info("{}-not- binding individual user", m);
} else {
logger.info("{}-binding- individual user", m);
if (password == null) {
logger.debug("{}null password", m);
if (USE_FILTER.equalsIgnoreCase(PW_NULL)) {
logger.debug("{}-no- pre null password handling", m);
} else {
if (AUTHENTICATE) {
logger.info("{}-doing- pre null password handling", m);
if (UNAUTHENTICATE_USER_UNCONDITIONALLY
.equalsIgnoreCase(PW_NULL)) {
logger.info("{}pre unauthenticating for null password", m);
throw new NamingException(msg + "null password]");
} else if (SKIP_FILTER.equalsIgnoreCase(PW_NULL)) {
logger.info("{}pre ignoring for null passwd", m);
throw new Exception(msg + "null password]");
}
}
}
} else if ("".equals(password)) {
logger.debug("{}0-length password", m);
if (USE_FILTER.equalsIgnoreCase(PW_0)) {
logger.debug("{}-no- pre 0-length password handling", m);
} else {
if (AUTHENTICATE) {
logger.info("{}-doing- pre 0-length password handling", m);
if (UNAUTHENTICATE_USER_UNCONDITIONALLY
.equalsIgnoreCase(PW_0)) {
logger.info("{}pre unauthenticating for 0-length password", m);
throw new NamingException(msg
+ "0-length password]");
} else if (SKIP_FILTER.equalsIgnoreCase(PW_0)) {
logger.info("{}pre ignoring for 0-length passwd", m);
throw new Exception(msg + "0-length password]");
}
}
}
} else {
assert password.length() > 0;
}
}
NamingEnumeration<SearchResult> ne = null;
try {
ne =
getBasicNamingEnumeration(userid,
password,
filter,
searchControls,
env);
assert ne != null;
if (ne.hasMoreElements()) {
logger.debug("{}enumeration has elements", m);
} else {
logger.debug("{}enumeration has no elements, yet no exceptions", m);
if (bindRequired() && !individualUserBind()) {
logger.debug("{}failed security bind", m);
throw new NamingException(msg + "failed security bind]");
}
if (!AUTHENTICATE) {
logger.debug("{}user authentication -not- done by this filter", m);
} else {
logger.debug("{}user authentication -done- by this filter", m);
if (!bindRequired()) {
logger.debug("{}but -not- binding", m);
} else {
logger.debug("{}-and- binding", m);
if (SKIP_FILTER.equalsIgnoreCase(EMPTY_RESULTS)) {
logger.debug("{}passing thru for EMPTY_RESULTS", m);
throw new Exception(msg + "null password]");
} else if (UNAUTHENTICATE_USER_UNCONDITIONALLY
.equalsIgnoreCase(EMPTY_RESULTS)) {
logger.debug("{}failing for EMPTY_RESULTS", m);
throw new NamingException(msg + "null password]");
} else if (USE_FILTER.equalsIgnoreCase(EMPTY_RESULTS)) {
logger.debug("{}passing for EMPTY_RESULTS", m);
//XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
} else if (UNAUTHENTICATE_USER_CONDITIONALLY
.equalsIgnoreCase(EMPTY_RESULTS)) {
if (ATTRIBUTES2RETURN == null
|| ATTRIBUTES2RETURN.length < 1) {
logger.debug("{}fair enough", m);
} else {
throw new NamingException(msg + "expected some");
}
}
}
}
}
} finally {
logger.debug("{}< {}", m, ne);
}
return ne;
}
private static Boolean comparePassword(Attributes attributes,
String password,
String passwordAttribute)
throws PasswordComparisonException {
String m = "- comparePassword() ";
logger.debug("{}>", m);
Boolean rc = null;
try {
logger.debug("{}looking for return attribute=={}", m, passwordAttribute);
Attribute attribute = attributes.get(passwordAttribute);
if (attribute == null) {
logger.error("{}null object", m);
} else {
int size = attribute.size();
logger.debug("{}object with n=={}", m, size);
for (int j = 0; j < size; j++) {
Object o = attribute.get(j);
if (password.equals(o.toString())) {
logger.debug("{}compares true", m);
if (rc == null) {
logger.debug("{}1st comp: authenticate", m);
rc = Boolean.TRUE;
} else {
logger.error("{}dup comp: keep previous rc=={}", m, rc);
}
} else {
logger.debug("{}compares false, -un-authenticate", m);
if (rc == null) {
logger.debug("{}1st comp (fyi)", m);
} else {
logger.error("{}dup comp (fyi)", m);
}
rc = Boolean.FALSE;
}
}
}
} catch (Throwable th) {
logger.error("{}resetting to null rc=={}{}",m, rc, th.getMessage());
throw new PasswordComparisonException("in ldap servlet filter", th);
} finally {
logger.debug("{}<{} ", m, rc);
}
return rc;
}
@SuppressWarnings("unchecked")
private void getAttributes(Attributes attributes, Map<String, Set<?>> map) throws Throwable {
String m =
FilterSetup.getFilterNameAbbrev(FILTER_NAME)
+ " getAttributes() ";
logger.debug("{}>", m);
try {
for (String key : ATTRIBUTES2RETURN) {
logger.debug("{}looking for return attribute=={}", m, key);
Attribute attribute = attributes.get(key);
if (attribute == null) {
logger.error("{}null object...continue to next attr sought", m);
continue;
}
if (GROUPS_NAME != null && !GROUPS_NAME.isEmpty()) {
key = GROUPS_NAME;
logger.debug("{}values collected and interpreted as groups=={}",
m, key);
}
Set<Object> values;
if (map.containsKey(key)) {
logger.debug("{}already a value-set for attribute=={}", m, key);
values = (Set<Object>) map.get(key);
} else {
logger.debug("{}making+storing a value-set for attribute=={}", m, key);
values = new HashSet<Object>();
map.put(key, values);
}
int size = attribute.size();
logger.debug("{}object with n=={}", m, size);
for (int j = 0; j < size; j++) {
Object o = attribute.get(j);
values.add(o);
logger.debug("{}added value=={}, class=={}", m, o, o.getClass().getName());
}
}
} finally {
logger.debug("{}<", m);
}
}
private Boolean processNamingEnumeration(NamingEnumeration<SearchResult> ne,
String password,
Boolean authenticated,
Map<String, Set<?>> map) {
String m =
FilterSetup.getFilterNameAbbrev(FILTER_NAME)
+ " processNamingEnumeration() ";
logger.debug("{}>", m);
try {
boolean errorOnSomeComparison = false;
while (ne.hasMoreElements()) {
logger.debug("{}another element", m);
SearchResult s = null;
try {
s = ne.nextElement();
logger.debug("{}got a {}", m, s.getClass().getName());
} catch (Throwable th) {
logger.error("{} naming enum contains obj not SearchResult", m);
continue;
}
Attributes attributes = s.getAttributes();
getAttributes(attributes, map);
if (individualUserComparison()) {
Boolean temp = null;
try {
temp = comparePassword(attributes, password, PASSWORD);
logger.debug("{}-this- comp yields {}", m, temp);
if (authenticated != null && !authenticated) {
logger.debug("{}keeping prev failed authn", m);
} else {
logger.debug("{}replacing prvsuccess or null authn", m);
if (errorOnSomeComparison) {
logger.debug("{}errorOnSomeComparison=={}",
m, errorOnSomeComparison);
} else {
authenticated = temp;
}
}
} catch (Throwable th) {
logger.debug("{}in iUC conditional, caught throwable th=={}",
m, th);
errorOnSomeComparison = true;
authenticated = null;
}
}
}
if (individualUserComparison()) {
if (errorOnSomeComparison) {
logger.debug("{}exception, so assuring authenticated=={}",
m, authenticated);
authenticated = null;
map.clear();
} else if (authenticated == null) {
authenticated = Boolean.FALSE;
logger.debug("{}no passwd attr found, so authenticated=={}",
m, authenticated);
}
}
} catch (Throwable th) { // play it safe:
map.clear();
if (authenticated != null && authenticated) {
// drop an earlier authentication, before exception was thrown
authenticated = null;
} // but leave alone a earlier -failed- authentication
if (LOG_STACK_TRACES) {
logger.error(m + "ldap filter failure", th);
} else {
logger.error(m + "ldap filter failure" + th.getMessage());
}
} finally {
logger.debug("{}< authenticated=={} map=={}",m,authenticated, map);
}
return authenticated;
}
@Override
public void populateCacheElement(CacheElement cacheElement, String password) {
//this is heavy on logging for field reporting
String m =
FilterSetup.getFilterNameAbbrev(FILTER_NAME)
+ " populateCacheElement() ";
logger.debug("{}>", m);
Boolean authenticated = null;
Map<String, Set<?>> map =
new Hashtable<String, Set<?>>();
try {
logger.debug("{}about to call getNamingEnumeration()", m);
String filter = getFilter(cacheElement.getUserid());
SearchControls searchControls = getSearchControls();
Hashtable<String,String> env = getEnvironment(cacheElement.getUserid(), password);
NamingEnumeration<SearchResult> ne = null;
try {
ne =
getNamingEnumeration(cacheElement.getUserid(),
password,
filter,
searchControls,
env);
assert ne != null;
logger.debug("{}got expected non-null ne, no exception thrown", m);
if (AUTHENTICATE && individualUserBind()) {
authenticated = Boolean.TRUE;
}
if (AUTHENTICATE && individualUserBind()
&& !authenticated.booleanValue()) {
logger.debug("{}-not- calling processNamingEnumeration()", m);
} else {
logger.debug("{}about to call processNamingEnumeration()", m);
assert map.isEmpty();
try {
authenticated =
processNamingEnumeration(ne,
password,
authenticated,
map);
logger.debug(m + "{}back from pNE. AUTHENTICATE=={} authenticated=={} map=={}",
m, AUTHENTICATE, authenticated, map);
if (authenticated != null) {
logger.debug("{}authenticated.booleanValue()=={}",
m, authenticated.booleanValue());
}
if (map != null) {
logger.debug("{}map.isEmpty()=={}", m, map.isEmpty());
}
if (AUTHENTICATE
&& (authenticated == null || !authenticated
.booleanValue())) {
map.clear();
}
logger.debug("{}before catch", m);
} catch (Throwable th) {
map.clear();
if (AUTHENTICATE && individualUserBind()) {
authenticated = Boolean.FALSE;
} else {
//to be sure: likely hasn't changed from initial
authenticated = null;
}
if (LOG_STACK_TRACES) {
logger.error("{}caught th=={}", m, th);
} else {
logger.error("{}caught th=={}", m, th.getMessage());
}
}
}
} catch (NamingException e) {
// the -error- logs here are because, though ne==null
// never before seen, yet hull log suggests caution and
// preemptive logging
logger.error("{}unexpected null ne w/o exception thrown", m);
if (!AUTHENTICATE) {
logger.error("{}wasn't authenticating", m);
} else {
authenticated = Boolean.FALSE;
if (individualUserComparison()) {
logger.error("{}can't do password comparison, so false", m);
} else if (individualUserBind()) {
logger.error("{}accept to mean failed bind, so false", m);
} else {
logger.error("{}authenticating, so now set false", m);
}
}
} catch (Exception e) {
// this seemingly was a condition reached at hull, of course
// though, in an earlier different code version
if (AUTHENTICATE && individualUserComparison()) {
authenticated = null; //Boolean.FALSE; PASSTHROUGH
logger.error(m + "has no ret vals, so reject authentication");
} else if (AUTHENTICATE && individualUserBind()) {
authenticated = null; //Boolean.FALSE; PASSTHROUGH
logger.error(m + "has no ret vals, so reject authentication");
}
}
} finally {
logger.debug("{}in finally, authenticated=={} map=={}",
m, authenticated, map);
cacheElement.populate(authenticated, null, map, null);
logger.debug("{}<", m);
}
}
}