binding custom flows
This commit is contained in:
1 parent
1ad7d4f1d8
commit
33e402e7be
31 files changed
+1074
-32
No files matched your search
@@ -6,12 +6,36 @@ import org.keycloak.models.UserModel;
|
||||
import org.keycloak.provider.Provider;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
* This interface is for users that want to add custom authenticators to an authentication flow.
|
||||
* You must implement this interface as well as an AuthenticatorFactory.
|
||||
*
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public interface Authenticator extends Provider {
|
||||
|
||||
/**
|
||||
* Initial call for the authenticator. If this is a form, a challenge with a Response rendering the form is usually sent
|
||||
*
|
||||
* @param context
|
||||
*/
|
||||
void authenticate(AuthenticatorContext context);
|
||||
|
||||
/**
|
||||
* Does this authenticator require that the user has already been identified? That AuthenticatorContext.getUser() is not null?
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
boolean requiresUser();
|
||||
|
||||
/**
|
||||
* Is this authenticator configured for this user.
|
||||
*
|
||||
* @param session
|
||||
* @param realm
|
||||
* @param user
|
||||
* @return
|
||||
*/
|
||||
boolean configuredFor(KeycloakSession session, RealmModel realm, UserModel user);
|
||||
|
||||
/**
|
||||
@@ -20,6 +44,11 @@ public interface Authenticator extends Provider {
|
||||
*/
|
||||
void setRequiredActions(KeycloakSession session, RealmModel realm, UserModel user);
|
||||
|
||||
/**
|
||||
* Usually implements a form action.
|
||||
*
|
||||
* @param context
|
||||
*/
|
||||
void action(AuthenticatorContext context);
|
||||
|
||||
|
||||
|
||||
@@ -6,6 +6,12 @@ import org.keycloak.provider.ConfiguredProvider;
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
|
||||
/**
|
||||
* Factory for creating Authenticator instances
|
||||
*
|
||||
* You must specify a file
|
||||
* META-INF/services/org.keycloak.authentication.AuthenticatorFactory in the jar that this class is contained in
|
||||
* This file must have the fully qualified class name of all your AuthentitoryFactory classes
|
||||
*
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
|
||||
+10
@@ -8,6 +8,11 @@ import org.keycloak.provider.ConfiguredProvider;
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public interface ConfigurableAuthenticatorFactory extends ConfiguredProvider {
|
||||
/**
|
||||
* Friendly name for the authenticator
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getDisplayType();
|
||||
|
||||
/**
|
||||
@@ -17,6 +22,11 @@ public interface ConfigurableAuthenticatorFactory extends ConfiguredProvider {
|
||||
*/
|
||||
String getReferenceCategory();
|
||||
|
||||
/**
|
||||
* Is this authenticator configurable?
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
boolean isConfigurable();
|
||||
|
||||
/**
|
||||
|
||||
+1
-1
@@ -263,7 +263,7 @@ public class AuthorizationEndpoint {
|
||||
clientSession.setNote(Details.AUTH_TYPE, CODE_AUTH_TYPE);
|
||||
|
||||
|
||||
AuthenticationFlowModel flow = realm.getFlowByAlias(DefaultAuthenticationFlows.BROWSER_FLOW);
|
||||
AuthenticationFlowModel flow = realm.getBrowserFlow();
|
||||
String flowId = flow.getId();
|
||||
AuthenticationProcessor processor = new AuthenticationProcessor();
|
||||
processor.setClientSession(clientSession)
|
||||
|
||||
@@ -331,7 +331,7 @@ public class TokenEndpoint {
|
||||
clientSession.setAuthMethod(OIDCLoginProtocol.LOGIN_PROTOCOL);
|
||||
clientSession.setAction(ClientSessionModel.Action.AUTHENTICATE.name());
|
||||
clientSession.setNote(OIDCLoginProtocol.ISSUER, Urls.realmIssuer(uriInfo.getBaseUri(), realm.getName()));
|
||||
AuthenticationFlowModel flow = realm.getFlowByAlias(DefaultAuthenticationFlows.DIRECT_GRANT_FLOW);
|
||||
AuthenticationFlowModel flow = realm.getDirectGrantFlow();
|
||||
String flowId = flow.getId();
|
||||
AuthenticationProcessor processor = new AuthenticationProcessor();
|
||||
processor.setClientSession(clientSession)
|
||||
|
||||
@@ -469,7 +469,7 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
|
||||
|
||||
protected Response browserAuthentication(ClientSessionModel clientSession, String errorMessage) {
|
||||
this.event.event(EventType.LOGIN);
|
||||
AuthenticationFlowModel flow = realmModel.getFlowByAlias(DefaultAuthenticationFlows.BROWSER_FLOW);
|
||||
AuthenticationFlowModel flow = realmModel.getBrowserFlow();
|
||||
String flowId = flow.getId();
|
||||
AuthenticationProcessor processor = new AuthenticationProcessor();
|
||||
processor.setClientSession(clientSession)
|
||||
|
||||
@@ -152,7 +152,7 @@ public class LoginActionsService {
|
||||
ClientSessionCode clientCode;
|
||||
Response response;
|
||||
|
||||
boolean verifyCode(String flow, String code, String requiredAction) {
|
||||
boolean verifyCode(AuthenticationFlowModel flow, String code, String requiredAction) {
|
||||
if (!verifyCode(flow, code)) {
|
||||
return false;
|
||||
} else if (!clientCode.isValidAction(requiredAction)) {
|
||||
@@ -175,7 +175,7 @@ public class LoginActionsService {
|
||||
}
|
||||
}
|
||||
|
||||
boolean verifyCode(String flow, String code, String requiredAction, String alternativeRequiredAction) {
|
||||
boolean verifyCode(AuthenticationFlowModel flow, String code, String requiredAction, String alternativeRequiredAction) {
|
||||
if (!verifyCode(flow, code)) {
|
||||
return false;
|
||||
} else if (!(clientCode.isValidAction(requiredAction) || clientCode.isValidAction(alternativeRequiredAction))) {
|
||||
@@ -201,7 +201,7 @@ public class LoginActionsService {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean verifyCode(String flow, String code) {
|
||||
public boolean verifyCode(AuthenticationFlowModel flow, String code) {
|
||||
if (!checkSsl()) {
|
||||
event.error(Errors.SSL_REQUIRED);
|
||||
response = ErrorPage.error(session, Messages.HTTPS_REQUIRED);
|
||||
@@ -268,7 +268,7 @@ public class LoginActionsService {
|
||||
@QueryParam("execution") String execution) {
|
||||
event.event(EventType.LOGIN);
|
||||
Checks checks = new Checks();
|
||||
if (!checks.verifyCode(DefaultAuthenticationFlows.BROWSER_FLOW, code, ClientSessionModel.Action.AUTHENTICATE.name(), ClientSessionModel.Action.RECOVER_PASSWORD.name())) {
|
||||
if (!checks.verifyCode(realm.getBrowserFlow(), code, ClientSessionModel.Action.AUTHENTICATE.name(), ClientSessionModel.Action.RECOVER_PASSWORD.name())) {
|
||||
return checks.response;
|
||||
}
|
||||
event.detail(Details.CODE_ID, code);
|
||||
@@ -284,12 +284,10 @@ public class LoginActionsService {
|
||||
}
|
||||
|
||||
protected Response processAuthentication(String execution, ClientSessionModel clientSession, String errorMessage) {
|
||||
String flowAlias = DefaultAuthenticationFlows.BROWSER_FLOW;
|
||||
return processFlow(execution, clientSession, flowAlias, errorMessage);
|
||||
return processFlow(execution, clientSession, realm.getBrowserFlow(), errorMessage);
|
||||
}
|
||||
|
||||
protected Response processFlow(String execution, ClientSessionModel clientSession, String flowAlias, String errorMessage) {
|
||||
AuthenticationFlowModel flow = realm.getFlowByAlias(flowAlias);
|
||||
protected Response processFlow(String execution, ClientSessionModel clientSession, AuthenticationFlowModel flow, String errorMessage) {
|
||||
AuthenticationProcessor processor = new AuthenticationProcessor();
|
||||
processor.setClientSession(clientSession)
|
||||
.setFlowId(flow.getId())
|
||||
@@ -325,7 +323,7 @@ public class LoginActionsService {
|
||||
@QueryParam("execution") String execution) {
|
||||
event.event(EventType.LOGIN);
|
||||
Checks checks = new Checks();
|
||||
if (!checks.verifyCode(DefaultAuthenticationFlows.BROWSER_FLOW, code, ClientSessionModel.Action.AUTHENTICATE.name())) {
|
||||
if (!checks.verifyCode(realm.getBrowserFlow(), code, ClientSessionModel.Action.AUTHENTICATE.name())) {
|
||||
return checks.response;
|
||||
}
|
||||
final ClientSessionCode clientCode = checks.clientCode;
|
||||
@@ -335,8 +333,7 @@ public class LoginActionsService {
|
||||
}
|
||||
|
||||
protected Response processRegistration(String execution, ClientSessionModel clientSession, String errorMessage) {
|
||||
String flowAlias = DefaultAuthenticationFlows.REGISTRATION_FLOW;
|
||||
return processFlow(execution, clientSession, flowAlias, errorMessage);
|
||||
return processFlow(execution, clientSession, realm.getRegistrationFlow(), errorMessage);
|
||||
}
|
||||
|
||||
|
||||
@@ -357,7 +354,7 @@ public class LoginActionsService {
|
||||
}
|
||||
|
||||
Checks checks = new Checks();
|
||||
if (!checks.verifyCode(DefaultAuthenticationFlows.REGISTRATION_FLOW, code, ClientSessionModel.Action.AUTHENTICATE.name())) {
|
||||
if (!checks.verifyCode(realm.getRegistrationFlow(), code, ClientSessionModel.Action.AUTHENTICATE.name())) {
|
||||
return checks.response;
|
||||
}
|
||||
event.detail(Details.CODE_ID, code);
|
||||
@@ -383,7 +380,7 @@ public class LoginActionsService {
|
||||
@QueryParam("execution") String execution) {
|
||||
event.event(EventType.REGISTER);
|
||||
Checks checks = new Checks();
|
||||
if (!checks.verifyCode(DefaultAuthenticationFlows.REGISTRATION_FLOW, code, ClientSessionModel.Action.AUTHENTICATE.name())) {
|
||||
if (!checks.verifyCode(realm.getRegistrationFlow(), code, ClientSessionModel.Action.AUTHENTICATE.name())) {
|
||||
return checks.response;
|
||||
}
|
||||
if (!realm.isRegistrationAllowed()) {
|
||||
@@ -484,7 +481,7 @@ public class LoginActionsService {
|
||||
final MultivaluedMap<String, String> formData) {
|
||||
event.event(EventType.UPDATE_PROFILE);
|
||||
Checks checks = new Checks();
|
||||
if (!checks.verifyCode(DefaultAuthenticationFlows.BROWSER_FLOW, code, ClientSessionModel.Action.UPDATE_PROFILE.name())) {
|
||||
if (!checks.verifyCode(realm.getBrowserFlow(), code, ClientSessionModel.Action.UPDATE_PROFILE.name())) {
|
||||
return checks.response;
|
||||
}
|
||||
ClientSessionCode accessCode = checks.clientCode;
|
||||
@@ -546,7 +543,7 @@ public class LoginActionsService {
|
||||
final MultivaluedMap<String, String> formData) {
|
||||
event.event(EventType.UPDATE_TOTP);
|
||||
Checks checks = new Checks();
|
||||
if (!checks.verifyCode(DefaultAuthenticationFlows.BROWSER_FLOW, code, ClientSessionModel.Action.CONFIGURE_TOTP.name())) {
|
||||
if (!checks.verifyCode(realm.getBrowserFlow(), code, ClientSessionModel.Action.CONFIGURE_TOTP.name())) {
|
||||
return checks.response;
|
||||
}
|
||||
ClientSessionCode accessCode = checks.clientCode;
|
||||
@@ -598,7 +595,7 @@ public class LoginActionsService {
|
||||
final MultivaluedMap<String, String> formData) {
|
||||
event.event(EventType.UPDATE_PASSWORD);
|
||||
Checks checks = new Checks();
|
||||
if (!checks.verifyCode(DefaultAuthenticationFlows.BROWSER_FLOW, code, ClientSessionModel.Action.UPDATE_PASSWORD.name(), ClientSessionModel.Action.RECOVER_PASSWORD.name())) {
|
||||
if (!checks.verifyCode(realm.getBrowserFlow(), code, ClientSessionModel.Action.UPDATE_PASSWORD.name(), ClientSessionModel.Action.RECOVER_PASSWORD.name())) {
|
||||
return checks.response;
|
||||
}
|
||||
ClientSessionCode accessCode = checks.clientCode;
|
||||
@@ -661,7 +658,7 @@ public class LoginActionsService {
|
||||
event.event(EventType.VERIFY_EMAIL);
|
||||
if (key != null) {
|
||||
Checks checks = new Checks();
|
||||
if (!checks.verifyCode(DefaultAuthenticationFlows.BROWSER_FLOW, key, ClientSessionModel.Action.VERIFY_EMAIL.name())) {
|
||||
if (!checks.verifyCode(realm.getBrowserFlow(), key, ClientSessionModel.Action.VERIFY_EMAIL.name())) {
|
||||
return checks.response;
|
||||
}
|
||||
ClientSessionCode accessCode = checks.clientCode;
|
||||
@@ -688,7 +685,7 @@ public class LoginActionsService {
|
||||
return AuthenticationManager.nextActionAfterAuthentication(session, userSession, clientSession, clientConnection, request, uriInfo, event);
|
||||
} else {
|
||||
Checks checks = new Checks();
|
||||
if (!checks.verifyCode(DefaultAuthenticationFlows.BROWSER_FLOW, code, ClientSessionModel.Action.VERIFY_EMAIL.name())) {
|
||||
if (!checks.verifyCode(realm.getBrowserFlow(), code, ClientSessionModel.Action.VERIFY_EMAIL.name())) {
|
||||
return checks.response;
|
||||
}
|
||||
ClientSessionCode accessCode = checks.clientCode;
|
||||
@@ -711,7 +708,7 @@ public class LoginActionsService {
|
||||
event.event(EventType.RESET_PASSWORD);
|
||||
if (key != null) {
|
||||
Checks checks = new Checks();
|
||||
if (!checks.verifyCode(DefaultAuthenticationFlows.BROWSER_FLOW, key, ClientSessionModel.Action.RECOVER_PASSWORD.name())) {
|
||||
if (!checks.verifyCode(realm.getBrowserFlow(), key, ClientSessionModel.Action.RECOVER_PASSWORD.name())) {
|
||||
return checks.response;
|
||||
}
|
||||
ClientSessionCode accessCode = checks.clientCode;
|
||||
@@ -732,7 +729,7 @@ public class LoginActionsService {
|
||||
final MultivaluedMap<String, String> formData) {
|
||||
event.event(EventType.SEND_RESET_PASSWORD);
|
||||
Checks checks = new Checks();
|
||||
if (!checks.verifyCode(DefaultAuthenticationFlows.BROWSER_FLOW, code)) {
|
||||
if (!checks.verifyCode(realm.getBrowserFlow(), code)) {
|
||||
return checks.response;
|
||||
}
|
||||
final ClientSessionCode accessCode = checks.clientCode;
|
||||
@@ -850,7 +847,7 @@ public class LoginActionsService {
|
||||
throw new WebApplicationException(ErrorPage.error(session, Messages.INVALID_CODE));
|
||||
}
|
||||
Checks checks = new Checks();
|
||||
if (!checks.verifyCode(DefaultAuthenticationFlows.BROWSER_FLOW, code, action)) {
|
||||
if (!checks.verifyCode(realm.getBrowserFlow(), code, action)) {
|
||||
return checks.response;
|
||||
}
|
||||
final ClientSessionCode clientCode = checks.clientCode;
|
||||
|
||||
Reference in new issue
Block a user