saml backchannel logout
This commit is contained in:
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);
|
||||
|
||||
Reference in new issue
Block a user