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 {
|
||||
/**
|
||||
* @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;
|
||||
|
||||
|
|
|
@ -191,6 +191,10 @@
|
|||
} else {
|
||||
kc.enableLogging = false;
|
||||
}
|
||||
|
||||
if (typeof initOptions.scope === "string") {
|
||||
kc.scope = initOptions.scope;
|
||||
}
|
||||
}
|
||||
|
||||
if (!kc.responseMode) {
|
||||
|
@ -433,15 +437,13 @@
|
|||
baseUrl = kc.endpoints.authorize();
|
||||
}
|
||||
|
||||
var scope;
|
||||
if (options && options.scope) {
|
||||
if (options.scope.indexOf("openid") != -1) {
|
||||
scope = options.scope;
|
||||
} else {
|
||||
scope = "openid " + options.scope;
|
||||
}
|
||||
} else {
|
||||
var scope = options && options.scope || kc.scope;
|
||||
if (!scope) {
|
||||
// if scope is not set, default to "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
|
||||
|
|
|
@ -42,11 +42,11 @@ public class JavascriptTestExecutor {
|
|||
}
|
||||
|
||||
public JavascriptTestExecutor login() {
|
||||
return login(null, null);
|
||||
return login((String)null, null);
|
||||
}
|
||||
|
||||
public JavascriptTestExecutor login(JavascriptStateValidator validator) {
|
||||
return login(null, validator);
|
||||
return login((String)null, validator);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -81,6 +81,10 @@ public class JavascriptTestExecutor {
|
|||
return this;
|
||||
}
|
||||
|
||||
public JavascriptTestExecutor login(JSObjectBuilder optionsBuilder, JavascriptStateValidator validator) {
|
||||
return login(optionsBuilder.build(), validator);
|
||||
}
|
||||
|
||||
public JavascriptTestExecutor login(String options, JavascriptStateValidator validator) {
|
||||
if (options == null)
|
||||
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.UserBuilder;
|
||||
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.XMLHttpRequest;
|
||||
import org.openqa.selenium.TimeoutException;
|
||||
|
@ -450,6 +451,53 @@ public class JavascriptAdapterTest extends AbstractJavascriptTest {
|
|||
.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
|
||||
public void testUpdateToken() {
|
||||
XMLHttpRequest request = XMLHttpRequest.create()
|
||||
|
|
Loading…
Reference in a new issue