Skip to content

Commit

Permalink
access code checks
Browse files Browse the repository at this point in the history
  • Loading branch information
patriot1burke committed Jun 16, 2015
1 parent 9638c0d commit cd84e78
Show file tree
Hide file tree
Showing 13 changed files with 89 additions and 42 deletions.
Expand Up @@ -11,7 +11,7 @@ public interface MigrationModel {
/** /**
* Must have the form of major.minor.micro as the version is parsed and numbers are compared * Must have the form of major.minor.micro as the version is parsed and numbers are compared
*/ */
public static final String LATEST_VERSION = "1.3.0.Beta1"; public static final String LATEST_VERSION = "1.4.0";


String getStoredVersion(); String getStoredVersion();
void setStoredVersion(String version); void setStoredVersion(String version);
Expand Down
Expand Up @@ -2,6 +2,7 @@


import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.keycloak.migration.migrators.MigrateTo1_3_0; import org.keycloak.migration.migrators.MigrateTo1_3_0;
import org.keycloak.migration.migrators.MigrateTo1_4_0;
import org.keycloak.migration.migrators.MigrationTo1_2_0_CR1; import org.keycloak.migration.migrators.MigrationTo1_2_0_CR1;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;


Expand Down Expand Up @@ -33,6 +34,12 @@ public static void migrate(KeycloakSession session) {
} }
new MigrateTo1_3_0().migrate(session); new MigrateTo1_3_0().migrate(session);
} }
if (stored == null || stored.lessThan(MigrateTo1_4_0.VERSION)) {
if (stored != null) {
logger.debug("Migrating older model to 1.4.0 updates");
}
new MigrateTo1_4_0().migrate(session);
}


model.setStoredVersion(MigrationModel.LATEST_VERSION); model.setStoredVersion(MigrationModel.LATEST_VERSION);
} }
Expand Down
@@ -0,0 +1,28 @@
package org.keycloak.migration.migrators;

import org.keycloak.migration.ModelVersion;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.utils.DefaultAuthenticationFlows;

import java.util.List;

/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class MigrateTo1_4_0 {
public static final ModelVersion VERSION = new ModelVersion("1.4.0");


public void migrate(KeycloakSession session) {
List<RealmModel> realms = session.realms().getRealms();
for (RealmModel realm : realms) {
if (realm.getAuthenticationFlows().size() == 0) {
DefaultAuthenticationFlows.addFlows(realm);
}

}

}
}
Expand Up @@ -19,6 +19,7 @@
import org.keycloak.services.ErrorPage; import org.keycloak.services.ErrorPage;
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.messages.Messages; import org.keycloak.services.messages.Messages;


import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
Expand Down Expand Up @@ -317,6 +318,13 @@ public EventBuilder getEvent() {
public String getForwardedErrorMessage() { public String getForwardedErrorMessage() {
return AuthenticationProcessor.this.forwardedErrorMessage; return AuthenticationProcessor.this.forwardedErrorMessage;
} }

@Override
public String generateAccessCode() {
ClientSessionCode accessCode = new ClientSessionCode(getRealm(), getClientSession());
accessCode.setAction(ClientSessionModel.Action.AUTHENTICATE.name());
return accessCode.getCode();
}
} }


public static class AuthException extends RuntimeException { public static class AuthException extends RuntimeException {
Expand Down Expand Up @@ -518,10 +526,7 @@ public Response processFlow(String flowId) {
if (model.isUserSetupAllowed()) { if (model.isUserSetupAllowed()) {
logger.debugv("authenticator SETUP_REQUIRED: {0}", authenticatorModel.getProviderId()); logger.debugv("authenticator SETUP_REQUIRED: {0}", authenticatorModel.getProviderId());
clientSession.setAuthenticatorStatus(model.getId(), UserSessionModel.AuthenticatorStatus.SETUP_REQUIRED); clientSession.setAuthenticatorStatus(model.getId(), UserSessionModel.AuthenticatorStatus.SETUP_REQUIRED);
String requiredAction = authenticator.getRequiredAction(); authenticator.setRequiredActions(session, realm, clientSession.getAuthenticatedUser());
if (!authUser.getRequiredActions().contains(requiredAction)) {
authUser.addRequiredAction(requiredAction);
}
continue; continue;
} else { } else {
throw new AuthException(Error.CREDENTIAL_SETUP_REQUIRED); throw new AuthException(Error.CREDENTIAL_SETUP_REQUIRED);
Expand Down
Expand Up @@ -13,7 +13,12 @@ public interface Authenticator extends Provider {
boolean requiresUser(); boolean requiresUser();
void authenticate(AuthenticatorContext context); void authenticate(AuthenticatorContext context);
boolean configuredFor(KeycloakSession session, RealmModel realm, UserModel user); boolean configuredFor(KeycloakSession session, RealmModel realm, UserModel user);
String getRequiredAction();
/**
* Set actions to configure authenticator
*
*/
void setRequiredActions(KeycloakSession session, RealmModel realm, UserModel user);




} }
Expand Up @@ -73,4 +73,11 @@ public interface AuthenticatorContext {
* whatever form is challenging. * whatever form is challenging.
*/ */
String getForwardedErrorMessage(); String getForwardedErrorMessage();

/**
* Generates access code and updates clientsession timestamp
*
* @return
*/
String generateAccessCode();
} }
Expand Up @@ -5,9 +5,7 @@
import org.keycloak.authentication.AuthenticatorContext; import org.keycloak.authentication.AuthenticatorContext;
import org.keycloak.events.Errors; import org.keycloak.events.Errors;
import org.keycloak.login.LoginFormsProvider; import org.keycloak.login.LoginFormsProvider;
import org.keycloak.models.ClientSessionModel;
import org.keycloak.models.UserModel; import org.keycloak.models.UserModel;
import org.keycloak.services.managers.ClientSessionCode;
import org.keycloak.services.messages.Messages; import org.keycloak.services.messages.Messages;
import org.keycloak.services.resources.LoginActionsService; import org.keycloak.services.resources.LoginActionsService;


Expand All @@ -29,48 +27,43 @@ protected boolean isAction(AuthenticatorContext context, String action) {
} }


protected LoginFormsProvider loginForm(AuthenticatorContext context) { protected LoginFormsProvider loginForm(AuthenticatorContext context) {
ClientSessionCode code = new ClientSessionCode(context.getRealm(), context.getClientSession()); String accessCode = context.generateAccessCode();
code.setAction(ClientSessionModel.Action.AUTHENTICATE.name()); URI action = getActionUrl(context, accessCode, LOGIN_FORM_ACTION);
URI action = getActionUrl(context, code, LOGIN_FORM_ACTION);
LoginFormsProvider provider = context.getSession().getProvider(LoginFormsProvider.class) LoginFormsProvider provider = context.getSession().getProvider(LoginFormsProvider.class)
.setUser(context.getUser()) .setUser(context.getUser())
.setActionUri(action) .setActionUri(action)
.setClientSessionCode(code.getCode()); .setClientSessionCode(accessCode);
if (context.getForwardedErrorMessage() != null) { if (context.getForwardedErrorMessage() != null) {
provider.setError(context.getForwardedErrorMessage()); provider.setError(context.getForwardedErrorMessage());
} }
return provider; return provider;
} }


public static URI getActionUrl(AuthenticatorContext context, ClientSessionCode code, String action) { public static URI getActionUrl(AuthenticatorContext context, String code, String action) {
return LoginActionsService.authenticationFormProcessor(context.getUriInfo()) return LoginActionsService.authenticationFormProcessor(context.getUriInfo())
.queryParam(OAuth2Constants.CODE, code.getCode()) .queryParam(OAuth2Constants.CODE, code)
.queryParam(ACTION, action) .queryParam(ACTION, action)
.build(context.getRealm().getName()); .build(context.getRealm().getName());
} }


protected Response invalidUser(AuthenticatorContext context) { protected Response invalidUser(AuthenticatorContext context) {
return loginForm(context) return loginForm(context)
.setError(Messages.INVALID_USER) .setError(Messages.INVALID_USER)
.setClientSessionCode(new ClientSessionCode(context.getRealm(), context.getClientSession()).getCode())
.createLogin(); .createLogin();
} }


protected Response disabledUser(AuthenticatorContext context) { protected Response disabledUser(AuthenticatorContext context) {
return loginForm(context) return loginForm(context)
.setClientSessionCode(new ClientSessionCode(context.getRealm(), context.getClientSession()).getCode())
.setError(Messages.ACCOUNT_DISABLED).createLogin(); .setError(Messages.ACCOUNT_DISABLED).createLogin();
} }


protected Response temporarilyDisabledUser(AuthenticatorContext context) { protected Response temporarilyDisabledUser(AuthenticatorContext context) {
return loginForm(context) return loginForm(context)
.setClientSessionCode(new ClientSessionCode(context.getRealm(), context.getClientSession()).getCode())
.setError(Messages.ACCOUNT_TEMPORARILY_DISABLED).createLogin(); .setError(Messages.ACCOUNT_TEMPORARILY_DISABLED).createLogin();
} }


protected Response invalidCredentials(AuthenticatorContext context) { protected Response invalidCredentials(AuthenticatorContext context) {
return loginForm(context) return loginForm(context)
.setClientSessionCode(new ClientSessionCode(context.getRealm(), context.getClientSession()).getCode())
.setError(Messages.INVALID_USER).createLogin(); .setError(Messages.INVALID_USER).createLogin();
} }


Expand Down
Expand Up @@ -38,8 +38,7 @@ public boolean configuredFor(KeycloakSession session, RealmModel realm, UserMode
} }


@Override @Override
public String getRequiredAction() { public void setRequiredActions(KeycloakSession session, RealmModel realm, UserModel user) {
return null;
} }


@Override @Override
Expand Down
Expand Up @@ -68,8 +68,11 @@ public boolean configuredFor(KeycloakSession session, RealmModel realm, UserMode
} }


@Override @Override
public String getRequiredAction() { public void setRequiredActions(KeycloakSession session, RealmModel realm, UserModel user) {
return UserModel.RequiredAction.CONFIGURE_TOTP.name(); if (!user.getRequiredActions().contains(UserModel.RequiredAction.CONFIGURE_TOTP.name())) {
user.addRequiredAction(UserModel.RequiredAction.CONFIGURE_TOTP.name());
}

} }


@Override @Override
Expand Down
Expand Up @@ -70,8 +70,11 @@ public boolean configuredFor(KeycloakSession session, RealmModel realm, UserMode
} }


@Override @Override
public String getRequiredAction() { public void setRequiredActions(KeycloakSession session, RealmModel realm, UserModel user) {
return UserModel.RequiredAction.UPDATE_PASSWORD.name(); if (!user.getRequiredActions().contains(UserModel.RequiredAction.UPDATE_PASSWORD.name())) {
user.addRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD.name());
}

} }


@Override @Override
Expand Down
Expand Up @@ -111,8 +111,7 @@ public boolean configuredFor(KeycloakSession session, RealmModel realm, UserMode
} }


@Override @Override
public String getRequiredAction() { public void setRequiredActions(KeycloakSession session, RealmModel realm, UserModel user) {
return null;
} }


@Override @Override
Expand Down
Expand Up @@ -11,7 +11,6 @@
import org.keycloak.models.UserCredentialModel; import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserModel; import org.keycloak.models.UserModel;
import org.keycloak.representations.idm.CredentialRepresentation; import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.services.managers.ClientSessionCode;
import org.keycloak.services.messages.Messages; import org.keycloak.services.messages.Messages;


import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.MultivaluedMap;
Expand Down Expand Up @@ -69,11 +68,11 @@ public boolean requiresUser() {
} }


protected Response challenge(AuthenticatorContext context, String error) { protected Response challenge(AuthenticatorContext context, String error) {
ClientSessionCode clientSessionCode = new ClientSessionCode(context.getRealm(), context.getClientSession()); String accessCode = context.generateAccessCode();
URI action = AbstractFormAuthenticator.getActionUrl(context, clientSessionCode, TOTP_FORM_ACTION); URI action = AbstractFormAuthenticator.getActionUrl(context, accessCode, TOTP_FORM_ACTION);
LoginFormsProvider forms = context.getSession().getProvider(LoginFormsProvider.class) LoginFormsProvider forms = context.getSession().getProvider(LoginFormsProvider.class)
.setActionUri(action) .setActionUri(action)
.setClientSessionCode(clientSessionCode.getCode()); .setClientSessionCode(accessCode);
if (error != null) forms.setError(error); if (error != null) forms.setError(error);


return forms.createLoginTotp(); return forms.createLoginTotp();
Expand All @@ -85,8 +84,11 @@ public boolean configuredFor(KeycloakSession session, RealmModel realm, UserMode
} }


@Override @Override
public String getRequiredAction() { public void setRequiredActions(KeycloakSession session, RealmModel realm, UserModel user) {
return UserModel.RequiredAction.CONFIGURE_TOTP.name(); if (!user.getRequiredActions().contains(UserModel.RequiredAction.CONFIGURE_TOTP.name())) {
user.addRequiredAction(UserModel.RequiredAction.CONFIGURE_TOTP.name());
}

} }


@Override @Override
Expand Down
Expand Up @@ -15,7 +15,6 @@
import org.keycloak.models.UserCredentialModel; import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserModel; import org.keycloak.models.UserModel;
import org.keycloak.models.UserSessionModel; import org.keycloak.models.UserSessionModel;
import org.keycloak.services.managers.ClientSessionCode;
import org.keycloak.services.messages.Messages; import org.keycloak.services.messages.Messages;


import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.HttpHeaders;
Expand Down Expand Up @@ -131,9 +130,8 @@ private Response challengeNegotiation(AuthenticatorContext context, final String
* @return * @return
*/ */
protected Response optionalChallengeRedirect(AuthenticatorContext context, String negotiateHeader) { protected Response optionalChallengeRedirect(AuthenticatorContext context, String negotiateHeader) {
ClientSessionCode code = new ClientSessionCode(context.getRealm(), context.getClientSession()); String accessCode = context.generateAccessCode();
code.setAction(ClientSessionModel.Action.AUTHENTICATE.name()); URI action = getActionUrl(context, accessCode, KERBEROS_DISABLED);
URI action = getActionUrl(context, code, KERBEROS_DISABLED);


StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();


Expand Down Expand Up @@ -162,11 +160,10 @@ protected Response optionalChallengeRedirect(AuthenticatorContext context, Strin
} }


protected Response formChallenge(AuthenticatorContext context, String negotiateHeader) { protected Response formChallenge(AuthenticatorContext context, String negotiateHeader) {
ClientSessionCode code = new ClientSessionCode(context.getRealm(), context.getClientSession()); String accessCode = context.generateAccessCode();
code.setAction(ClientSessionModel.Action.AUTHENTICATE.name()); URI action = getActionUrl(context, accessCode, KERBEROS_DISABLED);
URI action = getActionUrl(context, code, KERBEROS_DISABLED);
return context.getSession().getProvider(LoginFormsProvider.class) return context.getSession().getProvider(LoginFormsProvider.class)
.setClientSessionCode(new ClientSessionCode(context.getRealm(), context.getClientSession()).getCode()) .setClientSessionCode(accessCode)
.setActionUri(action) .setActionUri(action)
.setStatus(Response.Status.UNAUTHORIZED) .setStatus(Response.Status.UNAUTHORIZED)
.setResponseHeader(HttpHeaders.WWW_AUTHENTICATE, negotiateHeader) .setResponseHeader(HttpHeaders.WWW_AUTHENTICATE, negotiateHeader)
Expand All @@ -181,8 +178,7 @@ public boolean configuredFor(KeycloakSession session, RealmModel realm, UserMode
} }


@Override @Override
public String getRequiredAction() { public void setRequiredActions(KeycloakSession session, RealmModel realm, UserModel user) {
return null;
} }


@Override @Override
Expand Down

0 comments on commit cd84e78

Please sign in to comment.