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> <div>
<button onclick="keycloak.logout()">Log out</button> <button onclick="keycloak.logout()">Log out</button>
<button onclick="keycloak.updateToken()">Refresh token</button> <button onclick="keycloak.updateToken()">Refresh token</button>
<button onclick="keycloak.accountManagement()">Manage account</button>
</div> </div>
<div> <div>
<table> <table>

View file

@ -25,6 +25,6 @@ public interface Account {
public Account setRealm(RealmModel realm); 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 UserModel user;
private Response.Status status = Response.Status.OK; private Response.Status status = Response.Status.OK;
private RealmModel realm; private RealmModel realm;
private String referrer; private String[] referrer;
public static enum MessageType {SUCCESS, WARNING, ERROR} 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)); attributes.put("message", new MessageBean(messages.containsKey(message) ? messages.getProperty(message) : message, messageType));
} }
ApplicationModel referrerApp = getReferrer(); if (referrer != null) {
if (referrerApp != null) { attributes.put("referrer", new ReferrerBean(referrer));
attributes.put("referrer", new ReferrerBean(referrerApp));
} }
attributes.put("url", new UrlBean(realm, theme, baseUri)); 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 @Override
public Account setError(String message) { public Account setError(String message) {
this.message = message; this.message = message;
@ -164,7 +153,7 @@ public class FreeMarkerAccount implements Account {
} }
@Override @Override
public Account setReferrer(String referrer) { public Account setReferrer(String[] referrer) {
this.referrer = referrer; this.referrer = referrer;
return this; return this;
} }

View file

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

View file

@ -28,7 +28,7 @@
<div class="navbar-collapse navbar-collapse-1"> <div class="navbar-collapse navbar-collapse-1">
<div class="container"> <div class="container">
<ul class="nav navbar-nav navbar-utility"> <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> <li><a href="${url.logoutUrl}">Sign Out</a></li>
</ul> </ul>
</div> </div>

View file

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

View file

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

View file

@ -107,19 +107,7 @@ public class AccountTest {
}); });
} }
//@Test @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
public void returnToAppFromQueryParam() { public void returnToAppFromQueryParam() {
driver.navigate().to(AccountUpdateProfilePage.PATH + "?referrer=test-app"); driver.navigate().to(AccountUpdateProfilePage.PATH + "?referrer=test-app");
loginPage.login("test-user@localhost", "password"); loginPage.login("test-user@localhost", "password");
@ -127,6 +115,13 @@ public class AccountTest {
profilePage.backToApplication(); profilePage.backToApplication();
Assert.assertTrue(appPage.isCurrent()); 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 @Test

View file

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

View file

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