KEYCLOAK-1280: i18n logging for org.keycloak.authentication
This commit is contained in:
parent
7514104974
commit
3b4cb94ff1
4 changed files with 49 additions and 22 deletions
|
@ -1,6 +1,5 @@
|
||||||
package org.keycloak.authentication;
|
package org.keycloak.authentication;
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
|
||||||
import org.jboss.resteasy.spi.HttpRequest;
|
import org.jboss.resteasy.spi.HttpRequest;
|
||||||
import org.keycloak.common.ClientConnection;
|
import org.keycloak.common.ClientConnection;
|
||||||
import org.keycloak.OAuth2Constants;
|
import org.keycloak.OAuth2Constants;
|
||||||
|
@ -24,6 +23,7 @@ import org.keycloak.protocol.LoginProtocol;
|
||||||
import org.keycloak.protocol.LoginProtocol.Error;
|
import org.keycloak.protocol.LoginProtocol.Error;
|
||||||
import org.keycloak.protocol.oidc.TokenManager;
|
import org.keycloak.protocol.oidc.TokenManager;
|
||||||
import org.keycloak.services.ErrorPage;
|
import org.keycloak.services.ErrorPage;
|
||||||
|
import org.keycloak.services.ServicesLogger;
|
||||||
import org.keycloak.services.managers.AuthenticationManager;
|
import org.keycloak.services.managers.AuthenticationManager;
|
||||||
import org.keycloak.services.managers.BruteForceProtector;
|
import org.keycloak.services.managers.BruteForceProtector;
|
||||||
import org.keycloak.services.managers.ClientSessionCode;
|
import org.keycloak.services.managers.ClientSessionCode;
|
||||||
|
@ -44,7 +44,7 @@ import java.util.Map;
|
||||||
*/
|
*/
|
||||||
public class AuthenticationProcessor {
|
public class AuthenticationProcessor {
|
||||||
public static final String CURRENT_AUTHENTICATION_EXECUTION = "current.authentication.execution";
|
public static final String CURRENT_AUTHENTICATION_EXECUTION = "current.authentication.execution";
|
||||||
protected static Logger logger = Logger.getLogger(AuthenticationProcessor.class);
|
protected static final ServicesLogger logger = ServicesLogger.ROOT_LOGGER;
|
||||||
protected RealmModel realm;
|
protected RealmModel realm;
|
||||||
protected UserSessionModel userSession;
|
protected UserSessionModel userSession;
|
||||||
protected ClientSessionModel clientSession;
|
protected ClientSessionModel clientSession;
|
||||||
|
@ -539,25 +539,25 @@ public class AuthenticationProcessor {
|
||||||
if (failure instanceof AuthenticationFlowException) {
|
if (failure instanceof AuthenticationFlowException) {
|
||||||
AuthenticationFlowException e = (AuthenticationFlowException) failure;
|
AuthenticationFlowException e = (AuthenticationFlowException) failure;
|
||||||
if (e.getError() == AuthenticationFlowError.INVALID_USER) {
|
if (e.getError() == AuthenticationFlowError.INVALID_USER) {
|
||||||
logger.error("failed authentication: " + e.getError().toString(), e);
|
logger.failedAuthentication(e);
|
||||||
event.error(Errors.USER_NOT_FOUND);
|
event.error(Errors.USER_NOT_FOUND);
|
||||||
return ErrorPage.error(session, Messages.INVALID_USER);
|
return ErrorPage.error(session, Messages.INVALID_USER);
|
||||||
} else if (e.getError() == AuthenticationFlowError.USER_DISABLED) {
|
} else if (e.getError() == AuthenticationFlowError.USER_DISABLED) {
|
||||||
logger.error("failed authentication: " + e.getError().toString(), e);
|
logger.failedAuthentication(e);
|
||||||
event.error(Errors.USER_DISABLED);
|
event.error(Errors.USER_DISABLED);
|
||||||
return ErrorPage.error(session, Messages.ACCOUNT_DISABLED);
|
return ErrorPage.error(session, Messages.ACCOUNT_DISABLED);
|
||||||
} else if (e.getError() == AuthenticationFlowError.USER_TEMPORARILY_DISABLED) {
|
} else if (e.getError() == AuthenticationFlowError.USER_TEMPORARILY_DISABLED) {
|
||||||
logger.error("failed authentication: " + e.getError().toString(), e);
|
logger.failedAuthentication(e);
|
||||||
event.error(Errors.USER_TEMPORARILY_DISABLED);
|
event.error(Errors.USER_TEMPORARILY_DISABLED);
|
||||||
return ErrorPage.error(session, Messages.ACCOUNT_TEMPORARILY_DISABLED);
|
return ErrorPage.error(session, Messages.ACCOUNT_TEMPORARILY_DISABLED);
|
||||||
|
|
||||||
} else if (e.getError() == AuthenticationFlowError.INVALID_CLIENT_SESSION) {
|
} else if (e.getError() == AuthenticationFlowError.INVALID_CLIENT_SESSION) {
|
||||||
logger.error("failed authentication: " + e.getError().toString(), e);
|
logger.failedAuthentication(e);
|
||||||
event.error(Errors.INVALID_CODE);
|
event.error(Errors.INVALID_CODE);
|
||||||
return ErrorPage.error(session, Messages.INVALID_CODE);
|
return ErrorPage.error(session, Messages.INVALID_CODE);
|
||||||
|
|
||||||
} else if (e.getError() == AuthenticationFlowError.EXPIRED_CODE) {
|
} else if (e.getError() == AuthenticationFlowError.EXPIRED_CODE) {
|
||||||
logger.error("failed authentication: " + e.getError().toString(), e);
|
logger.failedAuthentication(e);
|
||||||
event.error(Errors.EXPIRED_CODE);
|
event.error(Errors.EXPIRED_CODE);
|
||||||
return ErrorPage.error(session, Messages.EXPIRED_CODE);
|
return ErrorPage.error(session, Messages.EXPIRED_CODE);
|
||||||
|
|
||||||
|
@ -580,13 +580,13 @@ public class AuthenticationProcessor {
|
||||||
return processor.authenticate();
|
return processor.authenticate();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
logger.error("failed authentication: " + e.getError().toString(), e);
|
logger.failedAuthentication(e);
|
||||||
event.error(Errors.INVALID_USER_CREDENTIALS);
|
event.error(Errors.INVALID_USER_CREDENTIALS);
|
||||||
return ErrorPage.error(session, Messages.INVALID_USER);
|
return ErrorPage.error(session, Messages.INVALID_USER);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
logger.error("failed authentication", failure);
|
logger.failedAuthentication(failure);
|
||||||
event.error(Errors.INVALID_USER_CREDENTIALS);
|
event.error(Errors.INVALID_USER_CREDENTIALS);
|
||||||
return ErrorPage.error(session, Messages.UNEXPECTED_ERROR_HANDLING_REQUEST);
|
return ErrorPage.error(session, Messages.UNEXPECTED_ERROR_HANDLING_REQUEST);
|
||||||
}
|
}
|
||||||
|
@ -596,7 +596,7 @@ public class AuthenticationProcessor {
|
||||||
public Response handleClientAuthException(Exception failure) {
|
public Response handleClientAuthException(Exception failure) {
|
||||||
if (failure instanceof AuthenticationFlowException) {
|
if (failure instanceof AuthenticationFlowException) {
|
||||||
AuthenticationFlowException e = (AuthenticationFlowException) failure;
|
AuthenticationFlowException e = (AuthenticationFlowException) failure;
|
||||||
logger.error("Failed client authentication: " + e.getError().toString(), e);
|
logger.failedClientAuthentication(e);
|
||||||
if (e.getError() == AuthenticationFlowError.CLIENT_NOT_FOUND) {
|
if (e.getError() == AuthenticationFlowError.CLIENT_NOT_FOUND) {
|
||||||
event.error(Errors.CLIENT_NOT_FOUND);
|
event.error(Errors.CLIENT_NOT_FOUND);
|
||||||
return ClientAuthUtil.errorResponse(Response.Status.BAD_REQUEST.getStatusCode(), "invalid_client", "Could not find client");
|
return ClientAuthUtil.errorResponse(Response.Status.BAD_REQUEST.getStatusCode(), "invalid_client", "Could not find client");
|
||||||
|
@ -611,7 +611,7 @@ public class AuthenticationProcessor {
|
||||||
return ClientAuthUtil.errorResponse(Response.Status.BAD_REQUEST.getStatusCode(), "unauthorized_client", e.getError().toString() + ": " + e.getMessage());
|
return ClientAuthUtil.errorResponse(Response.Status.BAD_REQUEST.getStatusCode(), "unauthorized_client", e.getError().toString() + ": " + e.getMessage());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
logger.error("Unexpected error when authenticating client", failure);
|
logger.errorAuthenticatingClient(failure);
|
||||||
event.error(Errors.INVALID_CLIENT_CREDENTIALS);
|
event.error(Errors.INVALID_CLIENT_CREDENTIALS);
|
||||||
return ClientAuthUtil.errorResponse(Response.Status.BAD_REQUEST.getStatusCode(), "unauthorized_client", "Unexpected error when authenticating client: " + failure.getMessage());
|
return ClientAuthUtil.errorResponse(Response.Status.BAD_REQUEST.getStatusCode(), "unauthorized_client", "Unexpected error when authenticating client: " + failure.getMessage());
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,12 +12,15 @@ import org.keycloak.models.AuthenticationExecutionModel;
|
||||||
import org.keycloak.models.AuthenticationFlowModel;
|
import org.keycloak.models.AuthenticationFlowModel;
|
||||||
import org.keycloak.models.ClientModel;
|
import org.keycloak.models.ClientModel;
|
||||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
|
import org.keycloak.services.ServicesLogger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
*/
|
*/
|
||||||
public class ClientAuthenticationFlow implements AuthenticationFlow {
|
public class ClientAuthenticationFlow implements AuthenticationFlow {
|
||||||
|
|
||||||
|
protected static final ServicesLogger logger = ServicesLogger.ROOT_LOGGER;
|
||||||
|
|
||||||
Response alternativeChallenge = null;
|
Response alternativeChallenge = null;
|
||||||
AuthenticationProcessor processor;
|
AuthenticationProcessor processor;
|
||||||
AuthenticationFlowModel flow;
|
AuthenticationFlowModel flow;
|
||||||
|
@ -42,7 +45,7 @@ public class ClientAuthenticationFlow implements AuthenticationFlow {
|
||||||
throw new AuthenticationFlowException("Could not find ClientAuthenticatorFactory for: " + model.getAuthenticator(), AuthenticationFlowError.INTERNAL_ERROR);
|
throw new AuthenticationFlowException("Could not find ClientAuthenticatorFactory for: " + model.getAuthenticator(), AuthenticationFlowError.INTERNAL_ERROR);
|
||||||
}
|
}
|
||||||
ClientAuthenticator authenticator = factory.create();
|
ClientAuthenticator authenticator = factory.create();
|
||||||
AuthenticationProcessor.logger.debugv("client authenticator: {0}", factory.getId());
|
logger.debugv("client authenticator: {0}", factory.getId());
|
||||||
|
|
||||||
AuthenticationProcessor.Result context = processor.createClientAuthenticatorContext(model, authenticator, executions);
|
AuthenticationProcessor.Result context = processor.createClientAuthenticatorContext(model, authenticator, executions);
|
||||||
authenticator.authenticateClient(context);
|
authenticator.authenticateClient(context);
|
||||||
|
@ -54,7 +57,7 @@ public class ClientAuthenticationFlow implements AuthenticationFlow {
|
||||||
// Fallback to secret just in case (for backwards compatibility)
|
// Fallback to secret just in case (for backwards compatibility)
|
||||||
if (expectedClientAuthType == null) {
|
if (expectedClientAuthType == null) {
|
||||||
expectedClientAuthType = KeycloakModelUtils.getDefaultClientAuthenticatorType();
|
expectedClientAuthType = KeycloakModelUtils.getDefaultClientAuthenticatorType();
|
||||||
AuthenticationProcessor.logger.warnv("Client {0} doesn't have have authentication method configured. Fallback to {1}", client.getClientId(), expectedClientAuthType);
|
logger.authMethodFallback(client.getClientId(), expectedClientAuthType);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if client authentication matches
|
// Check if client authentication matches
|
||||||
|
@ -66,7 +69,7 @@ public class ClientAuthenticationFlow implements AuthenticationFlow {
|
||||||
throw new AuthenticationFlowException("Expected success, but for an unknown reason the status was " + context.getStatus(), AuthenticationFlowError.INTERNAL_ERROR);
|
throw new AuthenticationFlowException("Expected success, but for an unknown reason the status was " + context.getStatus(), AuthenticationFlowError.INTERNAL_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
AuthenticationProcessor.logger.debugv("Client {0} authenticated by {1}", client.getClientId(), factory.getId());
|
logger.debugv("Client {0} authenticated by {1}", client.getClientId(), factory.getId());
|
||||||
processor.getEvent().detail(Details.CLIENT_AUTH_METHOD, factory.getId());
|
processor.getEvent().detail(Details.CLIENT_AUTH_METHOD, factory.getId());
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -96,12 +99,12 @@ public class ClientAuthenticationFlow implements AuthenticationFlow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (AuthenticationProcessor.logger.isTraceEnabled()) {
|
if (logger.isTraceEnabled()) {
|
||||||
List<String> exIds = new ArrayList<>();
|
List<String> exIds = new ArrayList<>();
|
||||||
for (AuthenticationExecutionModel execution : executionsToRun) {
|
for (AuthenticationExecutionModel execution : executionsToRun) {
|
||||||
exIds.add(execution.getId());
|
exIds.add(execution.getId());
|
||||||
}
|
}
|
||||||
AuthenticationProcessor.logger.tracef("Using executions for client authentication: %s", exIds.toString());
|
logger.tracef("Using executions for client authentication: %s", exIds.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
return executionsToRun;
|
return executionsToRun;
|
||||||
|
@ -111,7 +114,7 @@ public class ClientAuthenticationFlow implements AuthenticationFlow {
|
||||||
AuthenticationExecutionModel execution = result.getExecution();
|
AuthenticationExecutionModel execution = result.getExecution();
|
||||||
FlowStatus status = result.getStatus();
|
FlowStatus status = result.getStatus();
|
||||||
|
|
||||||
AuthenticationProcessor.logger.debugv("client authenticator {0}: {1}", status.toString(), execution.getAuthenticator());
|
logger.debugv("client authenticator {0}: {1}", status.toString(), execution.getAuthenticator());
|
||||||
|
|
||||||
if (status == FlowStatus.SUCCESS) {
|
if (status == FlowStatus.SUCCESS) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -135,13 +138,13 @@ public class ClientAuthenticationFlow implements AuthenticationFlow {
|
||||||
} else if (status == FlowStatus.FAILURE_CHALLENGE) {
|
} else if (status == FlowStatus.FAILURE_CHALLENGE) {
|
||||||
return sendChallenge(result, execution);
|
return sendChallenge(result, execution);
|
||||||
} else {
|
} else {
|
||||||
AuthenticationProcessor.logger.error("Unknown result status");
|
logger.unknownResultStatus();
|
||||||
throw new AuthenticationFlowException(AuthenticationFlowError.INTERNAL_ERROR);
|
throw new AuthenticationFlowException(AuthenticationFlowError.INTERNAL_ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Response sendChallenge(AuthenticationProcessor.Result result, AuthenticationExecutionModel execution) {
|
public Response sendChallenge(AuthenticationProcessor.Result result, AuthenticationExecutionModel execution) {
|
||||||
AuthenticationProcessor.logger.debugv("client authenticator: sending challenge for authentication execution {0}", execution.getAuthenticator());
|
logger.debugv("client authenticator: sending challenge for authentication execution {0}", execution.getAuthenticator());
|
||||||
|
|
||||||
if (result.getError() != null) {
|
if (result.getError() != null) {
|
||||||
String errorAsString = result.getError().toString().toLowerCase();
|
String errorAsString = result.getError().toString().toLowerCase();
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
package org.keycloak.authentication;
|
package org.keycloak.authentication;
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
|
||||||
import org.keycloak.models.AuthenticationExecutionModel;
|
import org.keycloak.models.AuthenticationExecutionModel;
|
||||||
import org.keycloak.models.AuthenticationFlowModel;
|
import org.keycloak.models.AuthenticationFlowModel;
|
||||||
import org.keycloak.models.ClientSessionModel;
|
import org.keycloak.models.ClientSessionModel;
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
|
import org.keycloak.services.ServicesLogger;
|
||||||
|
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
@ -15,7 +15,7 @@ import java.util.List;
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
public class DefaultAuthenticationFlow implements AuthenticationFlow {
|
public class DefaultAuthenticationFlow implements AuthenticationFlow {
|
||||||
protected static Logger logger = Logger.getLogger(DefaultAuthenticationFlow.class);
|
protected static final ServicesLogger logger = ServicesLogger.ROOT_LOGGER;
|
||||||
Response alternativeChallenge = null;
|
Response alternativeChallenge = null;
|
||||||
AuthenticationExecutionModel challengedAlternativeExecution = null;
|
AuthenticationExecutionModel challengedAlternativeExecution = null;
|
||||||
boolean alternativeSuccessful = false;
|
boolean alternativeSuccessful = false;
|
||||||
|
@ -222,7 +222,7 @@ public class DefaultAuthenticationFlow implements AuthenticationFlow {
|
||||||
return processor.authenticate();
|
return processor.authenticate();
|
||||||
default:
|
default:
|
||||||
logger.debugv("authenticator INTERNAL_ERROR: {0}", execution.getAuthenticator());
|
logger.debugv("authenticator INTERNAL_ERROR: {0}", execution.getAuthenticator());
|
||||||
logger.error("Unknown result status");
|
logger.unknownResultStatus();
|
||||||
throw new AuthenticationFlowException(AuthenticationFlowError.INTERNAL_ERROR);
|
throw new AuthenticationFlowException(AuthenticationFlowError.INTERNAL_ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,4 +86,28 @@ public interface ServicesLogger extends BasicLogger {
|
||||||
@LogMessage(level = ERROR)
|
@LogMessage(level = ERROR)
|
||||||
@Message(id=12, value="Failed to delete '%s'")
|
@Message(id=12, value="Failed to delete '%s'")
|
||||||
void failedToDeleteFile(String fileName);
|
void failedToDeleteFile(String fileName);
|
||||||
|
|
||||||
|
@LogMessage(level = ERROR)
|
||||||
|
@Message(id=13, value="failed authentication")
|
||||||
|
void failedAuthentication(@Cause Throwable t);
|
||||||
|
|
||||||
|
@LogMessage(level = ERROR)
|
||||||
|
@Message(id=14, value="Failed client authentication")
|
||||||
|
void failedClientAuthentication(@Cause Throwable t);
|
||||||
|
|
||||||
|
@LogMessage(level = ERROR)
|
||||||
|
@Message(id=15, value="Unexpected error when authenticating client")
|
||||||
|
void errorAuthenticatingClient(@Cause Throwable t);
|
||||||
|
|
||||||
|
@LogMessage(level = ERROR)
|
||||||
|
@Message(id=16, value="Unknown flow to execute with")
|
||||||
|
void unknownFlow();
|
||||||
|
|
||||||
|
@LogMessage(level = ERROR)
|
||||||
|
@Message(id=17, value="Unknown result status")
|
||||||
|
void unknownResultStatus();
|
||||||
|
|
||||||
|
@LogMessage(level = WARN)
|
||||||
|
@Message(id=18, value="Client %s doesn't have have authentication method configured. Fallback to %s")
|
||||||
|
void authMethodFallback(String clientId, String expectedClientAuthType);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue