KEYCLOAK-12908 TOTP not accepted in request for Access token
This commit is contained in:
parent
3f29c27e16
commit
a5d02d62c1
3 changed files with 51 additions and 0 deletions
|
@ -55,6 +55,8 @@ public interface OAuth2Constants {
|
||||||
|
|
||||||
String IMPLICIT = "implicit";
|
String IMPLICIT = "implicit";
|
||||||
|
|
||||||
|
String USERNAME="username";
|
||||||
|
|
||||||
String PASSWORD = "password";
|
String PASSWORD = "password";
|
||||||
|
|
||||||
String CLIENT_CREDENTIALS = "client_credentials";
|
String CLIENT_CREDENTIALS = "client_credentials";
|
||||||
|
|
|
@ -60,6 +60,9 @@ public class ValidateOTP extends AbstractDirectGrantAuthenticator implements Cre
|
||||||
|
|
||||||
String otp = inputData.getFirst("otp");
|
String otp = inputData.getFirst("otp");
|
||||||
|
|
||||||
|
// KEYCLOAK-12908 Backwards compatibility. If paramter "otp" is null, then assign "totp".
|
||||||
|
otp = (otp == null) ? inputData.getFirst("totp") : otp;
|
||||||
|
|
||||||
// Always use default OTP credential in case of direct grant authentication
|
// Always use default OTP credential in case of direct grant authentication
|
||||||
String credentialId = getCredentialProvider(context.getSession())
|
String credentialId = getCredentialProvider(context.getSession())
|
||||||
.getDefaultCredential(context.getSession(), context.getRealm(), context.getUser()).getId();
|
.getDefaultCredential(context.getSession(), context.getRealm(), context.getUser()).getId();
|
||||||
|
|
|
@ -21,7 +21,9 @@ import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.keycloak.OAuth2Constants;
|
||||||
import org.keycloak.events.Details;
|
import org.keycloak.events.Details;
|
||||||
|
import org.keycloak.models.Constants;
|
||||||
import org.keycloak.models.utils.TimeBasedOTP;
|
import org.keycloak.models.utils.TimeBasedOTP;
|
||||||
import org.keycloak.representations.idm.RealmRepresentation;
|
import org.keycloak.representations.idm.RealmRepresentation;
|
||||||
import org.keycloak.representations.idm.UserRepresentation;
|
import org.keycloak.representations.idm.UserRepresentation;
|
||||||
|
@ -32,11 +34,21 @@ import org.keycloak.testsuite.pages.AppPage.RequestType;
|
||||||
import org.keycloak.testsuite.pages.LoginPage;
|
import org.keycloak.testsuite.pages.LoginPage;
|
||||||
import org.keycloak.testsuite.pages.LoginTotpPage;
|
import org.keycloak.testsuite.pages.LoginTotpPage;
|
||||||
import org.keycloak.testsuite.util.GreenMailRule;
|
import org.keycloak.testsuite.util.GreenMailRule;
|
||||||
|
import org.keycloak.testsuite.util.OAuthClient;
|
||||||
import org.keycloak.testsuite.util.RealmRepUtil;
|
import org.keycloak.testsuite.util.RealmRepUtil;
|
||||||
import org.keycloak.testsuite.util.UserBuilder;
|
import org.keycloak.testsuite.util.UserBuilder;
|
||||||
|
|
||||||
|
import javax.ws.rs.client.Client;
|
||||||
|
import javax.ws.rs.client.ClientBuilder;
|
||||||
|
import javax.ws.rs.client.Entity;
|
||||||
|
import javax.ws.rs.client.WebTarget;
|
||||||
|
import javax.ws.rs.core.Form;
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
|
import java.io.IOException;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
|
|
||||||
|
import static org.keycloak.testsuite.auth.page.AuthRealm.TEST;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||||
* @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc.
|
* @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc.
|
||||||
|
@ -182,4 +194,38 @@ public class LoginTotpTest extends AbstractTestRealmKeycloakTest {
|
||||||
|
|
||||||
loginPage.assertCurrent();
|
loginPage.assertCurrent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//KEYCLOAK-12908
|
||||||
|
@Test
|
||||||
|
public void loginWithTotp_getToken_checkCompatibilityCLI() throws IOException {
|
||||||
|
Client httpClient = ClientBuilder.newClient();
|
||||||
|
try {
|
||||||
|
WebTarget exchangeUrl = httpClient.target(OAuthClient.AUTH_SERVER_ROOT)
|
||||||
|
.path("/realms")
|
||||||
|
.path(TEST)
|
||||||
|
.path("protocol/openid-connect/token");
|
||||||
|
|
||||||
|
Form form = new Form()
|
||||||
|
.param(OAuth2Constants.GRANT_TYPE, OAuth2Constants.PASSWORD)
|
||||||
|
.param(OAuth2Constants.USERNAME, "test-user@localhost")
|
||||||
|
.param(OAuth2Constants.PASSWORD, "password")
|
||||||
|
.param(OAuth2Constants.CLIENT_ID, Constants.ADMIN_CLI_CLIENT_ID);
|
||||||
|
|
||||||
|
// Compatibility between "otp" and "totp"
|
||||||
|
Response response = exchangeUrl.request()
|
||||||
|
.post(Entity.form(form.param("otp", totp.generateTOTP("totpSecret"))));
|
||||||
|
|
||||||
|
Assert.assertEquals(200, response.getStatus());
|
||||||
|
response.close();
|
||||||
|
|
||||||
|
response = exchangeUrl.request()
|
||||||
|
.post(Entity.form(form.param("totp", totp.generateTOTP("totpSecret"))));
|
||||||
|
|
||||||
|
Assert.assertEquals(200, response.getStatus());
|
||||||
|
response.close();
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
httpClient.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue