KEYCLOAK-5315 Conditional OTP enforcement does not work (#4399)

This commit is contained in:
Hisanobu Okuda 2017-09-13 13:58:59 +09:00 committed by Stian Thorgersen
parent 550e5f752a
commit b7af96aa4d
2 changed files with 85 additions and 0 deletions

View file

@ -300,10 +300,27 @@ public class ConditionalOtpFormAuthenticator extends OTPFormAuthenticator {
&& configModel.getConfig().size() <= 1) {
return true;
}
if (containsConditionalOtpConfig(configModel.getConfig())
&& voteForUserOtpControlAttribute(user, configModel.getConfig()) == ABSTAIN
&& voteForUserRole(realm, user, configModel.getConfig()) == ABSTAIN
&& voteForHttpHeaderMatchesPattern(requestHeaders, configModel.getConfig()) == ABSTAIN
&& (voteForDefaultFallback(configModel.getConfig()) == SHOW_OTP
|| voteForDefaultFallback(configModel.getConfig()) == ABSTAIN)) {
return true;
}
}
return false;
}
private boolean containsConditionalOtpConfig(Map config) {
return config.containsKey(OTP_CONTROL_USER_ATTRIBUTE)
|| config.containsKey(SKIP_OTP_ROLE)
|| config.containsKey(FORCE_OTP_ROLE)
|| config.containsKey(SKIP_OTP_FOR_HTTP_HEADER)
|| config.containsKey(FORCE_OTP_FOR_HTTP_HEADER)
|| config.containsKey(DEFAULT_OTP_OUTCOME);
}
@Override
public void setRequiredActions(KeycloakSession session, RealmModel realm, UserModel user) {
if (!isOTPRequired(session, realm, user)) {

View file

@ -175,6 +175,74 @@ public class CustomAuthFlowOTPTest extends AbstractCustomAccountManagementTest {
assertCurrentUrlStartsWith(testLoginOneTimeCodePage);
}
@Test
public void conditionalOTPNoDefaultWithChecks() {
configureRequiredActions();
configureOTP();
//prepare config - no configuration specified
Map<String, String> config = new HashMap<>();
config.put(OTP_CONTROL_USER_ATTRIBUTE, "noSuchUserSkipAttribute");
config.put(SKIP_OTP_ROLE, "no_such_otp_role");
config.put(FORCE_OTP_ROLE, "no_such_otp_role");
config.put(SKIP_OTP_FOR_HTTP_HEADER, "NoSuchHost: nolocalhost:65536");
config.put(FORCE_OTP_FOR_HTTP_HEADER, "NoSuchHost: nolocalhost:65536");
setConditionalOTPForm(config);
//test OTP is required
testRealmAccountManagementPage.navigateTo();
testRealmLoginPage.form().login(testUser);
testRealmLoginPage.form().totpForm().waitForTotpInputFieldPresent();
//verify that the page is login page, not totp setup
assertCurrentUrlStartsWith(testLoginOneTimeCodePage);
}
@Test
public void conditionalOTPDefaultSkipWithChecks() {
//prepare config - default skip
Map<String, String> config = new HashMap<>();
config.put(OTP_CONTROL_USER_ATTRIBUTE, "noSuchUserSkipAttribute");
config.put(SKIP_OTP_ROLE, "no_such_otp_role");
config.put(FORCE_OTP_ROLE, "no_such_otp_role");
config.put(SKIP_OTP_FOR_HTTP_HEADER, "NoSuchHost: nolocalhost:65536");
config.put(FORCE_OTP_FOR_HTTP_HEADER, "NoSuchHost: nolocalhost:65536");
config.put(DEFAULT_OTP_OUTCOME, SKIP);
setConditionalOTPForm(config);
//test OTP is skipped
testRealmAccountManagementPage.navigateTo();
testRealmLoginPage.form().login(testUser);
assertCurrentUrlStartsWith(testRealmAccountManagementPage);
}
@Test
public void conditionalOTPDefaultForceWithChecks() {
//prepare config - default force
Map<String, String> config = new HashMap<>();
config.put(OTP_CONTROL_USER_ATTRIBUTE, "noSuchUserSkipAttribute");
config.put(SKIP_OTP_ROLE, "no_such_otp_role");
config.put(FORCE_OTP_ROLE, "no_such_otp_role");
config.put(SKIP_OTP_FOR_HTTP_HEADER, "NoSuchHost: nolocalhost:65536");
config.put(FORCE_OTP_FOR_HTTP_HEADER, "NoSuchHost: nolocalhost:65536");
config.put(DEFAULT_OTP_OUTCOME, FORCE);
setConditionalOTPForm(config);
//test OTP is forced
testRealmAccountManagementPage.navigateTo();
testRealmLoginPage.form().login(testUser);
assertTrue(loginConfigTotpPage.isCurrent());
configureOTP();
testRealmLoginPage.form().login(testUser);
testRealmLoginPage.form().totpForm().waitForTotpInputFieldPresent();
//verify that the page is login page, not totp setup
assertCurrentUrlStartsWith(testLoginOneTimeCodePage);
}
@Test
public void conditionalOTPUserAttributeSkip() {
//prepare config - user attribute, default to force