saml backchannel logout

This commit is contained in:
Bill Burke committed 2014-10-07 18:06:02 -04:00
1 parent c609ae3496
commit 6d5ab0f66b
12 files changed
+615 -512

No files matched your search

@@ -22,14 +22,12 @@ public interface LoginProtocol extends Provider {
LoginProtocol setRealm(RealmModel realm);
LoginProtocol setRequest(HttpRequest request);
LoginProtocol setUriInfo(UriInfo uriInfo);
LoginProtocol setClientConnection(ClientConnection clientConnection);
Response cancelLogin(ClientSessionModel clientSession);
Response invalidSessionError(ClientSessionModel clientSession);
Response authenticated(UserSessionModel userSession, ClientSessionCode accessCode);
Response consentDenied(ClientSessionModel clientSession);
void backchannelLogout(UserSessionModel userSession, ClientSessionModel clientSession);
}
@@ -22,15 +22,18 @@
package org.keycloak.protocol.oidc;
import org.jboss.logging.Logger;
import org.jboss.resteasy.client.core.executors.ApacheHttpClient4Executor;
import org.jboss.resteasy.spi.HttpRequest;
import org.keycloak.ClientConnection;
import org.keycloak.OAuth2Constants;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.ClientSessionModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserSessionModel;
import org.keycloak.protocol.LoginProtocol;
import org.keycloak.services.managers.ClientSessionCode;
import org.keycloak.services.managers.ResourceAdminManager;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
@@ -56,19 +59,12 @@ public class OpenIDConnect implements LoginProtocol {
protected RealmModel realm;
protected HttpRequest request;
protected UriInfo uriInfo;
protected ClientConnection clientConnection;
public OpenIDConnect(KeycloakSession session, RealmModel realm, HttpRequest request, UriInfo uriInfo,
ClientConnection clientConnection) {
public OpenIDConnect(KeycloakSession session, RealmModel realm, UriInfo uriInfo) {
this.session = session;
this.realm = realm;
this.request = request;
this.uriInfo = uriInfo;
this.clientConnection = clientConnection;
}
public OpenIDConnect() {
@@ -86,24 +82,12 @@ public class OpenIDConnect implements LoginProtocol {
return this;
}
@Override
public OpenIDConnect setRequest(HttpRequest request) {
this.request = request;
return this;
}
@Override
public OpenIDConnect setUriInfo(UriInfo uriInfo) {
this.uriInfo = uriInfo;
return this;
}
@Override
public OpenIDConnect setClientConnection(ClientConnection clientConnection) {
this.clientConnection = clientConnection;
return this;
}
@Override
public Response cancelLogin(ClientSessionModel clientSession) {
String redirect = clientSession.getRedirectUri();
@@ -151,6 +135,19 @@ public class OpenIDConnect implements LoginProtocol {
return Response.status(302).location(redirectUri.build()).build();
}
@Override
public void backchannelLogout(UserSessionModel userSession, ClientSessionModel clientSession) {
if (!(clientSession.getClient() instanceof ApplicationModel)) return;
ApplicationModel app = (ApplicationModel)clientSession.getClient();
ApacheHttpClient4Executor executor = ResourceAdminManager.createExecutor();
try {
new ResourceAdminManager().logoutApplication(uriInfo.getRequestUri(), realm, app, null, userSession.getId(), executor, 0);
} finally {
executor.getHttpClient().getConnectionManager().shutdown();
}
}
@Override
public void close() {
@@ -800,7 +800,7 @@ public class OpenIDConnectService {
if (response != null) return response;
if (prompt != null && prompt.equals("none")) {
OpenIDConnect oauth = new OpenIDConnect(session, realm, request, uriInfo, clientConnection);
OpenIDConnect oauth = new OpenIDConnect(session, realm, uriInfo);
return oauth.cancelLogin(clientSession);
}
@@ -86,7 +86,17 @@ public class AuthenticationManager {
expireIdentityCookie(realm, uriInfo, connection);
expireRememberMeCookie(realm, uriInfo, connection);
new ResourceAdminManager().logoutUser(uriInfo.getRequestUri(), realm, user.getId(), userSession);
for (ClientSessionModel clientSession : userSession.getClientSessions()) {
ClientModel client = clientSession.getClient();
if (client instanceof ApplicationModel) {
String authMethod = clientSession.getAuthMethod();
if (authMethod == null) continue; // must be a keycloak service like account
LoginProtocol protocol = session.getProvider(LoginProtocol.class, authMethod);
protocol.setRealm(realm)
.setUriInfo(uriInfo);
protocol.backchannelLogout(userSession, clientSession);
}
}
session.sessions().removeUserSession(realm, userSession);
}
@@ -235,9 +245,7 @@ public class AuthenticationManager {
if (userSession.isRememberMe()) createRememberMeCookie(realm, userSession.getUser().getUsername(), uriInfo, clientConnection);
LoginProtocol protocol = session.getProvider(LoginProtocol.class, clientSession.getAuthMethod());
protocol.setRealm(realm)
.setRequest(request)
.setUriInfo(uriInfo)
.setClientConnection(clientConnection);
.setUriInfo(uriInfo);
return protocol.authenticated(userSession, new ClientSessionCode(realm, clientSession));
}
@@ -101,7 +101,7 @@ public class ResourceAdminManager {
}
protected String getManagementUrl(URI requestUri, ApplicationModel application) {
public static String getManagementUrl(URI requestUri, ApplicationModel application) {
String mgmtUrl = application.getManagementUrl();
if (mgmtUrl == null || mgmtUrl.equals("")) {
return null;
@@ -231,7 +231,7 @@ public class ResourceAdminManager {
}
protected boolean logoutApplication(URI requestUri, RealmModel realm, ApplicationModel resource, String user, String session, ApacheHttpClient4Executor client, int notBefore) {
public boolean logoutApplication(URI requestUri, RealmModel realm, ApplicationModel resource, String user, String session, ApacheHttpClient4Executor client, int notBefore) {
String managementUrl = getManagementUrl(requestUri, resource);
if (managementUrl != null) {
LogoutAction adminAction = new LogoutAction(TokenIdGenerator.generateId(), Time.currentTime() + 30, resource.getName(), user, session, notBefore);
@@ -309,9 +309,7 @@ public class LoginActionsService {
event.error(Errors.REJECTED_BY_USER);
LoginProtocol protocol = session.getProvider(LoginProtocol.class, clientSession.getAuthMethod());
protocol.setRealm(realm)
.setRequest(request)
.setUriInfo(uriInfo)
.setClientConnection(clientConnection);
.setUriInfo(uriInfo);
return protocol.cancelLogin(clientSession);
}
@@ -565,9 +563,7 @@ public class LoginActionsService {
LoginProtocol protocol = session.getProvider(LoginProtocol.class, clientSession.getAuthMethod());
protocol.setRealm(realm)
.setRequest(request)
.setUriInfo(uriInfo)
.setClientConnection(clientConnection);
.setUriInfo(uriInfo);
if (formData.containsKey("cancel")) {
event.error(Errors.REJECTED_BY_USER);
return protocol.consentDenied(clientSession);