KEYCLOAK-14412 Keycloak.js should honor scopes configured in initOptions and loginOptions
This commit is contained in:
parent
4946484cb6
commit
b926cd20f1
4 changed files with 66 additions and 11 deletions
|
@ -182,7 +182,8 @@ declare namespace Keycloak {
|
||||||
|
|
||||||
interface KeycloakLoginOptions {
|
interface KeycloakLoginOptions {
|
||||||
/**
|
/**
|
||||||
* @private Undocumented.
|
* Specifies the scope parameter for the login url
|
||||||
|
* The scope 'openid' will be added to the scope if it is missing or undefined.
|
||||||
*/
|
*/
|
||||||
scope?: string;
|
scope?: string;
|
||||||
|
|
||||||
|
|
|
@ -191,6 +191,10 @@
|
||||||
} else {
|
} else {
|
||||||
kc.enableLogging = false;
|
kc.enableLogging = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (typeof initOptions.scope === "string") {
|
||||||
|
kc.scope = initOptions.scope;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!kc.responseMode) {
|
if (!kc.responseMode) {
|
||||||
|
@ -433,15 +437,13 @@
|
||||||
baseUrl = kc.endpoints.authorize();
|
baseUrl = kc.endpoints.authorize();
|
||||||
}
|
}
|
||||||
|
|
||||||
var scope;
|
var scope = options && options.scope || kc.scope;
|
||||||
if (options && options.scope) {
|
if (!scope) {
|
||||||
if (options.scope.indexOf("openid") != -1) {
|
// if scope is not set, default to "openid"
|
||||||
scope = options.scope;
|
|
||||||
} else {
|
|
||||||
scope = "openid " + options.scope;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
scope = "openid";
|
scope = "openid";
|
||||||
|
} else if (scope.indexOf("openid") === -1) {
|
||||||
|
// if openid scope is missing, prefix the given scopes with it
|
||||||
|
scope = "openid " + scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
var url = baseUrl
|
var url = baseUrl
|
||||||
|
|
|
@ -42,11 +42,11 @@ public class JavascriptTestExecutor {
|
||||||
}
|
}
|
||||||
|
|
||||||
public JavascriptTestExecutor login() {
|
public JavascriptTestExecutor login() {
|
||||||
return login(null, null);
|
return login((String)null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public JavascriptTestExecutor login(JavascriptStateValidator validator) {
|
public JavascriptTestExecutor login(JavascriptStateValidator validator) {
|
||||||
return login(null, validator);
|
return login((String)null, validator);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -81,6 +81,10 @@ public class JavascriptTestExecutor {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public JavascriptTestExecutor login(JSObjectBuilder optionsBuilder, JavascriptStateValidator validator) {
|
||||||
|
return login(optionsBuilder.build(), validator);
|
||||||
|
}
|
||||||
|
|
||||||
public JavascriptTestExecutor login(String options, JavascriptStateValidator validator) {
|
public JavascriptTestExecutor login(String options, JavascriptStateValidator validator) {
|
||||||
if (options == null)
|
if (options == null)
|
||||||
jsExecutor.executeScript("keycloak.login()");
|
jsExecutor.executeScript("keycloak.login()");
|
||||||
|
|
|
@ -30,6 +30,7 @@ import org.keycloak.testsuite.util.OAuthClient;
|
||||||
import org.keycloak.testsuite.util.RealmBuilder;
|
import org.keycloak.testsuite.util.RealmBuilder;
|
||||||
import org.keycloak.testsuite.util.UserBuilder;
|
import org.keycloak.testsuite.util.UserBuilder;
|
||||||
import org.keycloak.testsuite.util.javascript.JSObjectBuilder;
|
import org.keycloak.testsuite.util.javascript.JSObjectBuilder;
|
||||||
|
import org.keycloak.testsuite.util.javascript.JavascriptStateValidator;
|
||||||
import org.keycloak.testsuite.util.javascript.JavascriptTestExecutor;
|
import org.keycloak.testsuite.util.javascript.JavascriptTestExecutor;
|
||||||
import org.keycloak.testsuite.util.javascript.XMLHttpRequest;
|
import org.keycloak.testsuite.util.javascript.XMLHttpRequest;
|
||||||
import org.openqa.selenium.TimeoutException;
|
import org.openqa.selenium.TimeoutException;
|
||||||
|
@ -450,6 +451,53 @@ public class JavascriptAdapterTest extends AbstractJavascriptTest {
|
||||||
.init(defaultArguments(), this::assertInitAuth);
|
.init(defaultArguments(), this::assertInitAuth);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for scope handling via {@code initOptions}: <pre>{@code
|
||||||
|
* Keycloak keycloak = new Keycloak(); keycloak.init({.... scope: "profile email phone"})
|
||||||
|
* }</pre>
|
||||||
|
* See KEYCLOAK-14412
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testScopeInInitOptionsShouldBeConsideredByLoginUrl() {
|
||||||
|
|
||||||
|
JSObjectBuilder initOptions = defaultArguments()
|
||||||
|
.loginRequiredOnLoad()
|
||||||
|
// phone is optional client scope
|
||||||
|
.add("scope", "profile email phone");
|
||||||
|
|
||||||
|
try {
|
||||||
|
testExecutor.init(initOptions);
|
||||||
|
// This throws exception because when JavascriptExecutor waits for AsyncScript to finish
|
||||||
|
// it is redirected to login page and executor gets no response
|
||||||
|
|
||||||
|
throw new RuntimeException("Probably the login-required OnLoad mode doesn't work, because testExecutor should fail with error that page was redirected.");
|
||||||
|
} catch (WebDriverException ex) {
|
||||||
|
// should happen
|
||||||
|
}
|
||||||
|
|
||||||
|
testExecutor.loginForm(testUser, this::assertOnTestAppUrl)
|
||||||
|
.init(initOptions, this::assertSuccessfullyLoggedIn)
|
||||||
|
.executeScript("return window.keycloak.tokenParsed.scope", assertOutputContains("phone"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for scope handling via {@code loginOptions}: <pre>{@code
|
||||||
|
* Keycloak keycloak = new Keycloak(); keycloak.login({.... scope: "profile email phone"})
|
||||||
|
* }</pre>
|
||||||
|
* See KEYCLOAK-14412
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testScopeInLoginOptionsShouldBeConsideredByLoginUrl() {
|
||||||
|
|
||||||
|
testExecutor.configure().init(defaultArguments());
|
||||||
|
|
||||||
|
JSObjectBuilder loginOptions = JSObjectBuilder.create().add("scope", "profile email phone");
|
||||||
|
|
||||||
|
testExecutor.login(loginOptions, (JavascriptStateValidator) (driver, output, events) -> {
|
||||||
|
assertThat(driver.getCurrentUrl(), containsString("&scope=openid%20profile%20email%20phone"));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUpdateToken() {
|
public void testUpdateToken() {
|
||||||
XMLHttpRequest request = XMLHttpRequest.create()
|
XMLHttpRequest request = XMLHttpRequest.create()
|
||||||
|
|
Loading…
Reference in a new issue