Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,12 @@ public static LDAPContextManager create(KeycloakSession session, LDAPConfig conn
return new LDAPContextManager(session, connectionProperties, requestTimer);
}

private void recordLdapRequest(boolean success, long startTimeNanos) {
private void recordLdapRequest(boolean success, long startTimeNanos, String error) {
if (requestTimer == null) {
return;
}
long durationNanos = System.nanoTime() - startTimeNanos;
requestTimer.withTags("operation", "connect", "outcome", success ? "success" : "error")
requestTimer.withTags("operation", "connect", "outcome", success ? "success" : "error", "error", error != null ? error : "")
.record(durationNanos, TimeUnit.NANOSECONDS);
}

Expand All @@ -81,6 +81,7 @@ private void createLdapContext() throws NamingException {

long startTimeNanos = System.nanoTime();
boolean success = false;
String errorName = null;

try {
Hashtable<Object, Object> connProp = getNonAuthConnectionProperties(ldapConfig);
Expand Down Expand Up @@ -116,11 +117,12 @@ private void createLdapContext() throws NamingException {
setAdminConnectionAuthProperties(ldapContext);
}
success = true;
} catch (NamingException e) {
} catch (NamingException | RuntimeException e) {
errorName = e.getClass().getSimpleName();
tracing.error(e);
throw e;
} finally {
recordLdapRequest(success, startTimeNanos);
recordLdapRequest(success, startTimeNanos, errorName);
tracing.endSpan();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,15 +95,15 @@ public LDAPOperationManager(KeycloakSession session, LDAPConfig config, Meter.Me
this.requestTimer = requestTimer;
}

private void recordLdapRequest(String operation, boolean success, long startTimeNanos) {
private void recordLdapRequest(String operation, boolean success, long startTimeNanos, String error) {
if (requestTimer == null) {
logger.debugf("LDAP request timer is null, skipping metric recording for operation: %s", operation);
return;
}
long durationNanos = System.nanoTime() - startTimeNanos;
logger.debugf("Recording LDAP metric - operation: %s, outcome: %s, duration: %d ns",
operation, success ? "success" : "error", durationNanos);
requestTimer.withTags("operation", operation, "outcome", success ? "success" : "error")
logger.debugf("Recording LDAP metric - operation: %s, outcome: %s, error: %s, duration: %d ns",
operation, success ? "success" : "error", error, durationNanos);
requestTimer.withTags("operation", operation, "outcome", success ? "success" : "error", "error", error != null ? error : "")
.record(durationNanos, TimeUnit.NANOSECONDS);
}

Expand Down Expand Up @@ -190,6 +190,10 @@ public SearchResult execute(LdapContext context) throws NamingException {
return null;
}

@Override
public String operationType() {
return "remove";
}

@Override
public String toString() {
Expand Down Expand Up @@ -247,6 +251,10 @@ public LdapName execute(LdapContext context) throws NamingException {
throw new ModelException("Could not rename entry from DN [" + oldDn + "] to new DN [" + newDn + "]. All fallbacks failed");
}

@Override
public String operationType() {
return "rename";
}

@Override
public String toString() {
Expand Down Expand Up @@ -293,6 +301,10 @@ public List<SearchResult> execute(LdapContext context) throws NamingException {
return result;
}

@Override
public String operationType() {
return "search";
}

@Override
public String toString() {
Expand Down Expand Up @@ -367,6 +379,10 @@ public List<SearchResult> execute(LdapContext context) throws NamingException {
}
}

@Override
public String operationType() {
return "searchPaginated";
}

@Override
public String toString() {
Expand Down Expand Up @@ -445,6 +461,10 @@ public SearchResult execute(LdapContext context) throws NamingException {
return null;
}

@Override
public String operationType() {
return "lookupById";
}

@Override
public String toString() {
Expand Down Expand Up @@ -519,6 +539,7 @@ public void authenticate(LdapName dn, String password) throws AuthenticationExce

long startTimeNanos = System.nanoTime();
boolean success = false;
String errorName = null;

try {
Hashtable<Object, Object> env = LDAPContextManager.getNonAuthConnectionProperties(config);
Expand Down Expand Up @@ -576,20 +597,23 @@ public void authenticate(LdapName dn, String password) throws AuthenticationExce
if (logger.isDebugEnabled()) {
logger.debugf(ae, "Authentication failed for DN [%s]", dn);
}
errorName = ae.getClass().getSimpleName();
tracing.error(ae);
throw ae;
} catch(RuntimeException re){
if (logger.isDebugEnabled()) {
logger.debugf(re, "LDAP Connection TimeOut for DN [%s]", dn);
}
errorName = re.getClass().getSimpleName();
tracing.error(re);
throw re;
} catch (Exception e) {
logger.errorf(e, "Unexpected exception when validating password of DN [%s]", dn);
errorName = e.getClass().getSimpleName();
tracing.error(e);
throw new AuthenticationException("Unexpected exception when validating password of user");
} finally {
recordLdapRequest("authenticate", success, startTimeNanos);
recordLdapRequest("authenticate", success, startTimeNanos, errorName);
if (tlsResponse != null) {
try {
tlsResponse.close();
Expand Down Expand Up @@ -641,6 +665,11 @@ public Void execute(LdapContext context) throws NamingException {
return null;
}

@Override
public String operationType() {
return "modify";
}

@Override
public String toString() {
return new StringBuilder("LdapOperation: modify\n")
Expand Down Expand Up @@ -700,6 +729,10 @@ public String execute(LdapContext context) throws NamingException {
}
}

@Override
public String operationType() {
return "create";
}

@Override
public String toString() {
Expand Down Expand Up @@ -759,9 +792,24 @@ public String decodeEntryUUID(final Object entryUUID) {

public void passwordModifyExtended(LdapName dn, String password, LDAPOperationDecorator decorator) {
try {
execute(context -> {
PasswordModifyRequest modifyRequest = new PasswordModifyRequest(dn.toString(), null, password);
return context.extendedOperation(modifyRequest);
execute(new LdapOperation<>() {
@Override
public Object execute(LdapContext context) throws NamingException {
PasswordModifyRequest modifyRequest = new PasswordModifyRequest(dn.toString(), null, password);
return context.extendedOperation(modifyRequest);
}

@Override
public String operationType() {
return "passwordModify";
}

@Override
public String toString() {
return new StringBuilder("LdapOperation: passwordModify\n")
.append(" dn: ").append(dn)
.toString();
}
}, decorator);
} catch (NamingException e) {
throw new ModelException("Could not execute the password modify extended operation for DN [" + dn + "]", e);
Expand Down Expand Up @@ -791,6 +839,7 @@ private <R> R execute(LdapOperation<R> operation, LdapContext context, LDAPOpera

long startTimeNanos = System.nanoTime();
boolean success = false;
String errorName = null;

var tracing = session.getProvider(TracingProvider.class);
var span = tracing.startSpan(LDAPOperationManager.class, "execute");
Expand All @@ -808,11 +857,12 @@ private <R> R execute(LdapOperation<R> operation, LdapContext context, LDAPOpera
R execute = operation.execute(context);
success = true;
return execute;
} catch (NamingException e) {
} catch (NamingException | RuntimeException e) {
errorName = e.getClass().getSimpleName();
tracing.error(e);
throw e;
} finally {
recordLdapRequest("execute", success, startTimeNanos);
recordLdapRequest(operation.operationType(), success, startTimeNanos, errorName);
tracing.endSpan();
if (perfLogger.isDebugEnabled()) {
long took = Time.currentTimeMillis() - start;
Expand All @@ -828,6 +878,10 @@ private <R> R execute(LdapOperation<R> operation, LdapContext context, LDAPOpera

public interface LdapOperation<R> {
R execute(LdapContext context) throws NamingException;

default String operationType() {
return "unknown";
}
}

private Set<String> getReturningAttributes(final Collection<String> returningAttributes) {
Expand Down
Loading