wip: move logic from validate to success

This commit is contained in:
knoflook 2023-12-11 15:17:55 +01:00
parent cd738a4a6f
commit 288029fe31
2 changed files with 178 additions and 122 deletions

View File

@ -32,7 +32,7 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>17</maven.compiler.source> <maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target> <maven.compiler.target>17</maven.compiler.target>
<keycloak.version>22.0.0</keycloak.version> <keycloak.version>23.0.0</keycloak.version>
</properties> </properties>
<dependencies> <dependencies>

View File

@ -1,20 +1,24 @@
package com.github.thomasdarimont.keycloak.auth; package com.github.thomasdarimont.keycloak.auth;
// //
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.keycloak.authentication.AuthenticationFlowError;
import org.keycloak.authentication.AuthenticationFlowException;
import org.keycloak.authentication.FormAction; import org.keycloak.authentication.FormAction;
import org.keycloak.authentication.ValidationContext; import org.keycloak.authentication.ValidationContext;
import org.keycloak.authentication.forms.RegistrationPage; import org.keycloak.authentication.forms.RegistrationPage;
import org.keycloak.authentication.forms.RegistrationProfile;
import org.keycloak.events.Details; import org.keycloak.events.Details;
import org.keycloak.events.Errors; import org.keycloak.events.Errors;
import org.keycloak.events.EventType;
import org.keycloak.models.AuthenticatorConfigModel; import org.keycloak.models.AuthenticatorConfigModel;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.models.UserModel; import org.keycloak.models.UserModel;
import org.keycloak.models.utils.FormMessage; import org.keycloak.models.utils.FormMessage;
import org.keycloak.provider.ProviderConfigProperty; import org.keycloak.provider.ProviderConfigProperty;
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
import org.keycloak.services.messages.Messages; import org.keycloak.services.messages.Messages;
import org.keycloak.services.validation.Validation; import org.keycloak.services.validation.Validation;
import org.keycloak.userprofile.UserProfile;
import jakarta.ws.rs.core.MultivaluedMap; import jakarta.ws.rs.core.MultivaluedMap;
import java.util.Arrays; import java.util.Arrays;
@ -52,10 +56,8 @@ public class RegistrationProfileDomainValidation extends RegistrationUserCreatio
rest = glob.substring(pos + 1); rest = glob.substring(pos + 1);
glob = glob.substring(0, pos); glob = glob.substring(0, pos);
} }
if (glob.length() > text.length()) if (glob.length() > text.length())
return false; return false;
// handle the part up to the first * // handle the part up to the first *
for (int i = 0; i < glob.length(); i++) for (int i = 0; i < glob.length(); i++)
if (glob.charAt(i) != '?' if (glob.charAt(i) != '?'
@ -75,6 +77,59 @@ public class RegistrationProfileDomainValidation extends RegistrationUserCreatio
} }
@Override @Override
public void success(FormContext context) {
if (context.getUser() != null) {
// the user probably did some back navigation in the browser, hitting this page in a strange state
context.getEvent().detail(Details.EXISTING_USER, context.getUser().getUsername());
throw new AuthenticationFlowException(AuthenticationFlowError.GENERIC_AUTHENTICATION_ERROR, Errors.DIFFERENT_USER_AUTHENTICATING, Messages.EXPIRED_ACTION);
}
MultivaluedMap<String, String> formData = context.getHttpRequest().getDecodedFormParameters();
String email = formData.getFirst(UserModel.EMAIL);
String username = formData.getFirst(UserModel.USERNAME);
if (context.getRealm().isRegistrationEmailAsUsername()) {
username = email;
}
// get the allowlist of mail domains
AuthenticatorConfigModel mailDomainConfig = context.getAuthenticatorConfig();
String eventError = Errors.INVALID_REGISTRATION;
String[] domainList = getDomainList(mailDomainConfig);
boolean emailDomainValid = isEmailValid(email, domainList);
context.getEvent().detail(Details.USERNAME, username).detail(Details.REGISTER_METHOD, "form").detail(Details.EMAIL, email);
UserProfile profile = getOrCreateUserProfile(context, formData);
UserModel user = profile.create();
if (!emailDomainValid)
user.addRequiredAction("USER_MUST_BE_APPROVED");
user.setEnabled(true);
context.setUser(user);
if (!emailDomainValid) {
user.addRequiredAction("USER_MUST_BE_APPROVED");
}
context.getAuthenticationSession().setClientNote(OIDCLoginProtocol.LOGIN_HINT_PARAM, username);
context.getEvent().user(user);
context.getEvent().success();
context.newEvent().event(EventType.LOGIN);
context.getEvent().client(context.getAuthenticationSession().getClient().getClientId())
.detail(Details.REDIRECT_URI, context.getAuthenticationSession().getRedirectUri())
.detail(Details.AUTH_METHOD, context.getAuthenticationSession().getProtocol());
String authType = context.getAuthenticationSession().getAuthNote(Details.AUTH_TYPE);
if (authType != null) {
context.getEvent().detail(Details.AUTH_TYPE, authType);
}
}
/* @Override
public void validate(ValidationContext context) { public void validate(ValidationContext context) {
MultivaluedMap<String, String> formData = context.getHttpRequest().getDecodedFormParameters(); MultivaluedMap<String, String> formData = context.getHttpRequest().getDecodedFormParameters();
@ -111,7 +166,8 @@ public class RegistrationProfileDomainValidation extends RegistrationUserCreatio
} else { } else {
context.success(); context.success();
} }
} */
public String[] getDomainList(AuthenticatorConfigModel mailDomainConfig) { public String[] getDomainList(AuthenticatorConfigModel mailDomainConfig) {
return mailDomainConfig.getConfig().getOrDefault(domainListConfigName, DEFAULT_DOMAIN_LIST).split(DOMAIN_LIST_SEPARATOR); return mailDomainConfig.getConfig().getOrDefault(domainListConfigName, DEFAULT_DOMAIN_LIST).split(DOMAIN_LIST_SEPARATOR);