-
-
Notifications
You must be signed in to change notification settings - Fork 114
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
135 additions
and
0 deletions.
There are no files selected for viewing
52 changes: 52 additions & 0 deletions
52
...in/java/dasniko/keycloak/authentication/conditional/AbstractConditionalAuthenticator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package dasniko.keycloak.authentication.conditional; | ||
|
||
import org.keycloak.Config; | ||
import org.keycloak.authentication.AuthenticationFlowContext; | ||
import org.keycloak.authentication.authenticators.conditional.ConditionalAuthenticator; | ||
import org.keycloak.authentication.authenticators.conditional.ConditionalAuthenticatorFactory; | ||
import org.keycloak.models.AuthenticationExecutionModel; | ||
import org.keycloak.models.KeycloakSession; | ||
import org.keycloak.models.KeycloakSessionFactory; | ||
import org.keycloak.models.RealmModel; | ||
import org.keycloak.models.UserModel; | ||
import org.keycloak.provider.ProviderConfigProperty; | ||
|
||
public abstract class AbstractConditionalAuthenticator implements ConditionalAuthenticatorFactory, ConditionalAuthenticator { | ||
|
||
static final String CONF_NOT = "not"; | ||
|
||
static final AuthenticationExecutionModel.Requirement[] REQUIREMENT_CHOICES = {AuthenticationExecutionModel.Requirement.REQUIRED, AuthenticationExecutionModel.Requirement.DISABLED}; | ||
|
||
ProviderConfigProperty negateOutputConfProperty = new ProviderConfigProperty(CONF_NOT, "Negate output", "Apply a NOT to the check result", ProviderConfigProperty.BOOLEAN_TYPE, false); | ||
|
||
@Override | ||
public ConditionalAuthenticator getSingleton() { | ||
return this; | ||
} | ||
|
||
@Override | ||
public AuthenticationExecutionModel.Requirement[] getRequirementChoices() { | ||
return REQUIREMENT_CHOICES; | ||
} | ||
|
||
@Override | ||
public void init(Config.Scope config) { | ||
} | ||
|
||
@Override | ||
public void postInit(KeycloakSessionFactory factory) { | ||
} | ||
|
||
@Override | ||
public void close() { | ||
} | ||
|
||
@Override | ||
public void action(AuthenticationFlowContext authenticationFlowContext) { | ||
} | ||
|
||
@Override | ||
public void setRequiredActions(KeycloakSession keycloakSession, RealmModel realmModel, UserModel userModel) { | ||
} | ||
|
||
} |
83 changes: 83 additions & 0 deletions
83
...rc/main/java/dasniko/keycloak/authentication/conditional/ConditionalAmrAuthenticator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
package dasniko.keycloak.authentication.conditional; | ||
|
||
import com.google.auto.service.AutoService; | ||
import de.keycloak.util.AuthenticatorUtil; | ||
import lombok.extern.jbosslog.JBossLog; | ||
import org.keycloak.authentication.AuthenticationFlowContext; | ||
import org.keycloak.authentication.AuthenticatorFactory; | ||
import org.keycloak.authentication.authenticators.util.AuthenticatorUtils; | ||
import org.keycloak.models.Constants; | ||
import org.keycloak.protocol.oidc.utils.AmrUtils; | ||
import org.keycloak.provider.ProviderConfigProperty; | ||
|
||
import java.util.List; | ||
import java.util.Map; | ||
|
||
@JBossLog | ||
@AutoService(AuthenticatorFactory.class) | ||
public class ConditionalAmrAuthenticator extends AbstractConditionalAuthenticator { | ||
|
||
public static final String PROVIDER_ID = "conditional-amr"; | ||
|
||
static final String CONF_AMR_VALUE = "amr_value"; | ||
|
||
@Override | ||
public boolean matchCondition(AuthenticationFlowContext context) { | ||
String expectedValue = AuthenticatorUtil.getConfig(context, CONF_AMR_VALUE, ""); | ||
List<String> amrValues = getAmr(context); | ||
boolean negateOutput = AuthenticatorUtil.getConfig(context, ConditionalAuthNoteAuthenticatorFactory.CONF_NOT, Boolean.FALSE); | ||
|
||
return negateOutput != amrValues.contains(expectedValue); | ||
} | ||
|
||
@Override | ||
public boolean requiresUser() { | ||
return false; | ||
} | ||
|
||
@Override | ||
public String getDisplayType() { | ||
return "Condition - Authentication Method Reference"; | ||
} | ||
|
||
@Override | ||
public boolean isConfigurable() { | ||
return true; | ||
} | ||
|
||
@Override | ||
public boolean isUserSetupAllowed() { | ||
return false; | ||
} | ||
|
||
@Override | ||
public String getHelpText() { | ||
return "...some help text..."; | ||
} | ||
|
||
@Override | ||
public List<ProviderConfigProperty> getConfigProperties() { | ||
ProviderConfigProperty amrExpectedValue = new ProviderConfigProperty(); | ||
amrExpectedValue.setType(ProviderConfigProperty.STRING_TYPE); | ||
amrExpectedValue.setName(CONF_AMR_VALUE); | ||
amrExpectedValue.setLabel("AMR value"); | ||
amrExpectedValue.setHelpText("Expected authenticator method reference value."); | ||
|
||
return List.of(amrExpectedValue, negateOutputConfProperty); | ||
} | ||
|
||
@Override | ||
public String getId() { | ||
return PROVIDER_ID; | ||
} | ||
|
||
protected List<String> getAmr(AuthenticationFlowContext context) { | ||
Map<String, String> userSessionNotes = context.getAuthenticationSession().getUserSessionNotes(); | ||
Map<String, Integer> executions = AuthenticatorUtils.parseCompletedExecutions(userSessionNotes.get(Constants.AUTHENTICATORS_COMPLETED)); | ||
log.debugf("found the following completed authentication executions: %s", executions.toString()); | ||
List<String> refs = AmrUtils.getAuthenticationExecutionReferences(executions, context.getRealm()); | ||
log.debugf("amr %s set in session", refs); | ||
return refs; | ||
} | ||
|
||
} |