KEYCLOAK-3774 Fix keycloak.js with prompt=none and new stricter redirect_uri

This commit is contained in:
Stian Thorgersen 2016-10-20 16:06:51 +02:00
parent 1bf24d26a4
commit 9801f09a93
4 changed files with 17 additions and 39 deletions

View file

@ -210,11 +210,18 @@
var nonce = createUUID(); var nonce = createUUID();
var redirectUri = adapter.redirectUri(options); var redirectUri = adapter.redirectUri(options);
if (options && options.prompt) {
redirectUri += (redirectUri.indexOf('?') == -1 ? '?' : '&') + 'prompt=' + options.prompt; var callbackState = {
state: state,
nonce: nonce,
redirectUri: encodeURIComponent(redirectUri),
} }
callbackStorage.add({ state: state, nonce: nonce, redirectUri: encodeURIComponent(redirectUri) }); if (options && options.prompt) {
callbackState.prompt = options.prompt;
}
callbackStorage.add(callbackState);
var action = 'auth'; var action = 'auth';
if (options && options.action == 'register') { if (options && options.action == 'register') {
@ -747,6 +754,7 @@
if (oauthState && (oauth.code || oauth.error || oauth.access_token || oauth.id_token)) { if (oauthState && (oauth.code || oauth.error || oauth.access_token || oauth.id_token)) {
oauth.redirectUri = oauthState.redirectUri; oauth.redirectUri = oauthState.redirectUri;
oauth.storedNonce = oauthState.nonce; oauth.storedNonce = oauthState.nonce;
oauth.prompt = oauthState.prompt;
if (oauth.fragment) { if (oauth.fragment) {
oauth.newUrl += '#' + oauth.fragment; oauth.newUrl += '#' + oauth.fragment;
@ -1218,9 +1226,6 @@
case 'redirect_fragment': case 'redirect_fragment':
oauth.fragment = queryParams[param]; oauth.fragment = queryParams[param];
break; break;
case 'prompt':
oauth.prompt = queryParams[param];
break;
default: default:
if (responseMode != 'query' || !handleQueryParam(param, queryParams[param], oauth)) { if (responseMode != 'query' || !handleQueryParam(param, queryParams[param], oauth)) {
oauth.newUrl += (oauth.newUrl.indexOf('?') == -1 ? '?' : '&') + param + '=' + queryParams[param]; oauth.newUrl += (oauth.newUrl.indexOf('?') == -1 ? '?' : '&') + param + '=' + queryParams[param];

View file

@ -21,13 +21,16 @@
var init; var init;
function checkState(clientId, origin, sessionState, callback) { function checkState(clientId, origin, sessionState, callback) {
if (!init) { var cookie = getCookie();
if (!cookie) {
callback('changed');
} else if (!init) {
var req = new XMLHttpRequest(); var req = new XMLHttpRequest();
var url = location.href + "/init"; var url = location.href + "/init";
url += "?client_id=" + encodeURIComponent(clientId); url += "?client_id=" + encodeURIComponent(clientId);
url += "&origin=" + encodeURIComponent(origin); url += "&origin=" + encodeURIComponent(origin);
url += "&session_state=" + encodeURIComponent(sessionState);
req.open('GET', url, true); req.open('GET', url, true);
@ -50,7 +53,6 @@
req.send(); req.send();
} else { } else {
if (clientId == init.clientId && origin == init.origin) { if (clientId == init.clientId && origin == init.origin) {
var cookie = getCookie();
if (sessionState == cookie) { if (sessionState == cookie) {
callback('unchanged'); callback('unchanged');
} else { } else {

View file

@ -68,27 +68,19 @@ public class LoginStatusIframeEndpoint {
@GET @GET
@Path("init") @Path("init")
public Response preCheck(@QueryParam("client_id") String clientId, @QueryParam("origin") String origin, @QueryParam("session_state") String sessionState) { public Response preCheck(@QueryParam("client_id") String clientId, @QueryParam("origin") String origin) {
try { try {
RealmModel realm = session.getContext().getRealm(); RealmModel realm = session.getContext().getRealm();
String sessionId = sessionState.split("/")[2];
UserSessionModel userSession = session.sessions().getUserSession(realm, sessionId);
if (userSession == null) {
return Response.status(Response.Status.NOT_FOUND).build();
}
ClientModel client = session.realms().getClientByClientId(clientId, realm); ClientModel client = session.realms().getClientByClientId(clientId, realm);
if (client != null) { if (client != null) {
Set<String> validWebOrigins = WebOriginsUtils.resolveValidWebOrigins(uriInfo, client); Set<String> validWebOrigins = WebOriginsUtils.resolveValidWebOrigins(uriInfo, client);
validWebOrigins.add(UriUtils.getOrigin(uriInfo.getRequestUri())); validWebOrigins.add(UriUtils.getOrigin(uriInfo.getRequestUri()));
if (validWebOrigins.contains(origin)) { if (validWebOrigins.contains(origin)) {
return Response.noContent().build(); return Response.noContent().build();
} }
} }
} catch (Throwable t) { } catch (Throwable t) {
} }
return Response.status(Response.Status.FORBIDDEN).build(); return Response.status(Response.Status.FORBIDDEN).build();
} }

View file

@ -133,7 +133,6 @@ public class LoginStatusIframeEndpointTest extends AbstractKeycloakTest {
get = new HttpGet(suiteContext.getAuthServerInfo().getContextRoot() + "/auth/realms/master/protocol/openid-connect/login-status-iframe.html/init?" get = new HttpGet(suiteContext.getAuthServerInfo().getContextRoot() + "/auth/realms/master/protocol/openid-connect/login-status-iframe.html/init?"
+ "client_id=invalid" + "client_id=invalid"
+ "&session_state=" + sessionCookie.getValue()
+ "&origin=" + suiteContext.getAuthServerInfo().getContextRoot() + "&origin=" + suiteContext.getAuthServerInfo().getContextRoot()
); );
response = client.execute(get); response = client.execute(get);
@ -142,16 +141,6 @@ public class LoginStatusIframeEndpointTest extends AbstractKeycloakTest {
get = new HttpGet(suiteContext.getAuthServerInfo().getContextRoot() + "/auth/realms/master/protocol/openid-connect/login-status-iframe.html/init?" get = new HttpGet(suiteContext.getAuthServerInfo().getContextRoot() + "/auth/realms/master/protocol/openid-connect/login-status-iframe.html/init?"
+ "client_id=" + Constants.ADMIN_CONSOLE_CLIENT_ID + "client_id=" + Constants.ADMIN_CONSOLE_CLIENT_ID
+ "&session_state=invalid"
+ "&origin=" + suiteContext.getAuthServerInfo().getContextRoot()
);
response = client.execute(get);
assertEquals(403, response.getStatusLine().getStatusCode());
response.close();
get = new HttpGet(suiteContext.getAuthServerInfo().getContextRoot() + "/auth/realms/master/protocol/openid-connect/login-status-iframe.html/init?"
+ "client_id=" + Constants.ADMIN_CONSOLE_CLIENT_ID
+ "&session_state=" + sessionCookie.getValue()
+ "&origin=http://invalid" + "&origin=http://invalid"
); );
response = client.execute(get); response = client.execute(get);
@ -160,16 +149,6 @@ public class LoginStatusIframeEndpointTest extends AbstractKeycloakTest {
get = new HttpGet(suiteContext.getAuthServerInfo().getContextRoot() + "/auth/realms/master/protocol/openid-connect/login-status-iframe.html/init?" get = new HttpGet(suiteContext.getAuthServerInfo().getContextRoot() + "/auth/realms/master/protocol/openid-connect/login-status-iframe.html/init?"
+ "client_id=" + Constants.ADMIN_CONSOLE_CLIENT_ID + "client_id=" + Constants.ADMIN_CONSOLE_CLIENT_ID
+ "&session_state=master/random/random"
+ "&origin=" + suiteContext.getAuthServerInfo().getContextRoot()
);
response = client.execute(get);
assertEquals(404, response.getStatusLine().getStatusCode());
response.close();
get = new HttpGet(suiteContext.getAuthServerInfo().getContextRoot() + "/auth/realms/master/protocol/openid-connect/login-status-iframe.html/init?"
+ "client_id=" + Constants.ADMIN_CONSOLE_CLIENT_ID
+ "&session_state=" + sessionCookie.getValue()
+ "&origin=" + suiteContext.getAuthServerInfo().getContextRoot() + "&origin=" + suiteContext.getAuthServerInfo().getContextRoot()
); );
response = client.execute(get); response = client.execute(get);