Fixes to account referrer to allow configurable referrer uri based on app redirect uri

This commit is contained in:
Stian Thorgersen 2014-03-19 16:32:51 +00:00
parent b5bdeae2a2
commit 702ae0307e
10 changed files with 55 additions and 53 deletions

View file

@ -42,6 +42,7 @@
<div>
<button onclick="keycloak.logout()">Log out</button>
<button onclick="keycloak.updateToken()">Refresh token</button>
<button onclick="keycloak.accountManagement()">Manage account</button>
</div>
<div>
<table>

View file

@ -25,6 +25,6 @@ public interface Account {
public Account setRealm(RealmModel realm);
public Account setReferrer(String referrer);
public Account setReferrer(String[] referrer);
}

View file

@ -36,7 +36,7 @@ public class FreeMarkerAccount implements Account {
private UserModel user;
private Response.Status status = Response.Status.OK;
private RealmModel realm;
private String referrer;
private String[] referrer;
public static enum MessageType {SUCCESS, WARNING, ERROR}
@ -82,9 +82,8 @@ public class FreeMarkerAccount implements Account {
attributes.put("message", new MessageBean(messages.containsKey(message) ? messages.getProperty(message) : message, messageType));
}
ApplicationModel referrerApp = getReferrer();
if (referrerApp != null) {
attributes.put("referrer", new ReferrerBean(referrerApp));
if (referrer != null) {
attributes.put("referrer", new ReferrerBean(referrer));
}
attributes.put("url", new UrlBean(realm, theme, baseUri));
@ -114,16 +113,6 @@ public class FreeMarkerAccount implements Account {
}
}
private ApplicationModel getReferrer() {
if (referrer != null) {
ApplicationModel app = realm.getApplicationByName(referrer);
if (app != null) {
return app;
}
}
return null;
}
@Override
public Account setError(String message) {
this.message = message;
@ -164,7 +153,7 @@ public class FreeMarkerAccount implements Account {
}
@Override
public Account setReferrer(String referrer) {
public Account setReferrer(String[] referrer) {
this.referrer = referrer;
return this;
}

View file

@ -1,24 +1,22 @@
package org.keycloak.account.freemarker.model;
import org.keycloak.models.ApplicationModel;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class ReferrerBean {
private ApplicationModel referrer;
private String[] referrer;
public ReferrerBean(ApplicationModel referrer) {
public ReferrerBean(String[] referrer) {
this.referrer = referrer;
}
public String getName() {
return referrer.getName();
return referrer[0];
}
public String getBaseUrl() {
return referrer.getBaseUrl();
public String getUrl() {
return referrer[1];
}
}

View file

@ -28,7 +28,7 @@
<div class="navbar-collapse navbar-collapse-1">
<div class="container">
<ul class="nav navbar-nav navbar-utility">
<#if referrer?has_content && referrer.baseUrl?has_content><li><a href="${referrer.baseUrl}">Back to ${referrer.name}</a></li></#if>
<#if referrer?has_content && referrer.url?has_content><li><a href="${referrer.url}" id="referrer">Back to ${referrer.name}</a></li></#if>
<li><a href="${url.logoutUrl}">Sign Out</a></li>
</ul>
</div>

View file

@ -103,10 +103,11 @@ var Keycloak = function (config) {
return url;
}
kc.createAccountUrl = function() {
kc.createAccountUrl = function(options) {
var url = getRealmUrl()
+ '/account'
+ '?referrer=' + kc.clientId;
+ '?referrer=' + kc.clientId
+ '&referrer_uri=' + encodeURIComponent(adapter.redirectUri(options));
return url;
}

View file

@ -99,7 +99,7 @@ public class AccountService {
Account account = AccountLoader.load().createAccount(uriInfo).setRealm(realm).setUser(auth.getUser());
String referrer = getReferrer();
String[] referrer = getReferrer();
if (referrer != null) {
account.setReferrer(referrer);
}
@ -377,13 +377,17 @@ public class AccountService {
uriBuilder.queryParam("path", path);
}
String referrer = getReferrer();
String referrer = uriInfo.getQueryParameters().getFirst("referrer");
if (referrer != null) {
uriBuilder.queryParam("referrer", referrer);
}
URI accountUri = uriBuilder.build(realm.getName());
String referrerUri = uriInfo.getQueryParameters().getFirst("referrer_uri");
if (referrerUri != null) {
uriBuilder.queryParam("referrer_uri", referrerUri);
}
URI accountUri = uriBuilder.build(realm.getName());
oauth.setStateCookiePath(accountUri.getRawPath());
return oauth.redirect(uriInfo, accountUri.toString());
@ -397,20 +401,34 @@ public class AccountService {
return auth;
}
private String getReferrer() {
private String[] getReferrer() {
String referrer = uriInfo.getQueryParameters().getFirst("referrer");
if (referrer != null) {
return referrer;
if (referrer == null) {
return null;
}
String referrerUrl = headers.getHeaderString("Referer");
if (referrerUrl != null) {
for (ApplicationModel a : realm.getApplications()) {
if (a.getBaseUrl() != null && referrerUrl.startsWith(a.getBaseUrl())) {
return a.getName();
String referrerUri = uriInfo.getQueryParameters().getFirst("referrer_uri");
ApplicationModel application = realm.getApplicationByName(referrer);
if (application != null) {
if (referrerUri != null) {
referrerUri = TokenService.verifyRedirectUri(referrerUri, application);
} else {
referrerUri = application.getBaseUrl();
}
if (referrerUri != null) {
return new String[] { referrer, referrerUri };
}
} else if (referrerUri != null) {
ClientModel client = realm.getOAuthClient(referrer);
if (client != null) {
referrerUri = TokenService.verifyRedirectUri(referrerUri, application);
if (referrerUri != null) {
return new String[] { referrer, referrerUri };
}
}
return null;
}
return null;

View file

@ -107,19 +107,7 @@ public class AccountTest {
});
}
//@Test
public void returnToAppFromHeader() {
appPage.open();
appPage.openAccount();
loginPage.login("test-user@localhost", "password");
Assert.assertTrue(profilePage.isCurrent());
profilePage.backToApplication();
Assert.assertTrue(appPage.isCurrent());
}
//@Test
@Test
public void returnToAppFromQueryParam() {
driver.navigate().to(AccountUpdateProfilePage.PATH + "?referrer=test-app");
loginPage.login("test-user@localhost", "password");
@ -127,6 +115,13 @@ public class AccountTest {
profilePage.backToApplication();
Assert.assertTrue(appPage.isCurrent());
driver.navigate().to(AccountUpdateProfilePage.PATH + "?referrer=test-app&referrer_uri=http://localhost:8081/app?test");
Assert.assertTrue(profilePage.isCurrent());
profilePage.backToApplication();
Assert.assertTrue(appPage.isCurrent());
Assert.assertEquals(appPage.baseUrl + "?test", driver.getCurrentUrl());
}
@Test

View file

@ -42,7 +42,7 @@ public class AccountUpdateProfilePage extends AbstractAccountPage {
private WebElement emailInput;
@FindBy(linkText = "Back to application")
@FindBy(id = "referrer")
private WebElement backToApplicationLink;
@FindBy(css = "button[type=\"submit\"]")

View file

@ -30,7 +30,7 @@ import org.openqa.selenium.support.FindBy;
*/
public class AppPage extends AbstractPage {
private String baseUrl = "http://localhost:8081/app";
public static final String baseUrl = "http://localhost:8081/app";
@FindBy(id = "account")
private WebElement accountLink;