GUACAMOLE-519: Merge Single Logout for OpenID Extension
This commit is contained in:
5 files changed
+177
-3
No files matched your search
+23
-1
@@ -63,6 +63,28 @@ public interface SSOAuthenticationProviderService {
|
|||||||
*/
|
*/
|
||||||
URI getLoginURI() throws GuacamoleException;
|
URI getLoginURI() throws GuacamoleException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the full URI of the logout endpoint to which a user should be
|
||||||
|
* redirected when they log out from Guacamole. This allows the user to
|
||||||
|
* also log out from the SSO identity provider. If no logout endpoint is
|
||||||
|
* configured, null is returned.
|
||||||
|
*
|
||||||
|
* @param idToken
|
||||||
|
* The ID token or authentication token from the user's session, if
|
||||||
|
* available. This may be used as an id_token_hint parameter in the
|
||||||
|
* logout request. May be null if not available.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* The full URI of the SSO logout endpoint, or null if not configured.
|
||||||
|
*
|
||||||
|
* @throws GuacamoleException
|
||||||
|
* If configuration information required for generating the logout URI
|
||||||
|
* cannot be read.
|
||||||
|
*/
|
||||||
|
default URI getLogoutURI(String idToken) throws GuacamoleException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Frees all resources associated with the relevant
|
* Frees all resources associated with the relevant
|
||||||
* SSOAuthenticationProvider implementation. This function is automatically
|
* SSOAuthenticationProvider implementation. This function is automatically
|
||||||
@@ -70,5 +92,5 @@ public interface SSOAuthenticationProviderService {
|
|||||||
* down.
|
* down.
|
||||||
*/
|
*/
|
||||||
void shutdown();
|
void shutdown();
|
||||||
|
|
||||||
}
|
}
|
||||||
+31
@@ -19,9 +19,11 @@
|
|||||||
package org.apache.guacamole.auth.sso;
|
package org.apache.guacamole.auth.sso;
|
||||||
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
|
import java.net.URI;
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
import javax.ws.rs.GET;
|
import javax.ws.rs.GET;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.QueryParam;
|
||||||
import org.apache.guacamole.GuacamoleException;
|
import org.apache.guacamole.GuacamoleException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -55,4 +57,33 @@ public class SSOResource {
|
|||||||
return Response.seeOther(authService.getLoginURI()).build();
|
return Response.seeOther(authService.getLoginURI()).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redirects the user to the identity provider's logout endpoint, if
|
||||||
|
* configured. This allows the user to log out from both Guacamole and the
|
||||||
|
* SSO identity provider. If no logout endpoint is configured, a 204 No
|
||||||
|
* Content response is returned.
|
||||||
|
*
|
||||||
|
* @param idToken
|
||||||
|
* The ID token from the user's authentication session, if available.
|
||||||
|
* This will be included as the id_token_hint parameter in the logout
|
||||||
|
* request. May be null.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* An HTTP Response that will redirect the user to the IdP logout
|
||||||
|
* endpoint if configured, or a 204 No Content response otherwise.
|
||||||
|
*
|
||||||
|
* @throws GuacamoleException
|
||||||
|
* If an error occurs preventing the redirect from being created.
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@Path("logout")
|
||||||
|
public Response getLogoutRedirect(
|
||||||
|
@QueryParam("id_token") String idToken) throws GuacamoleException {
|
||||||
|
URI logoutURI = authService.getLogoutURI(idToken);
|
||||||
|
if (logoutURI != null)
|
||||||
|
return Response.seeOther(logoutURI).build();
|
||||||
|
else
|
||||||
|
return Response.noContent().build();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+25
-1
@@ -130,9 +130,33 @@ public class AuthenticationProviderService implements SSOAuthenticationProviderS
|
|||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public URI getLogoutURI(String idToken) throws GuacamoleException {
|
||||||
|
|
||||||
|
// If no logout endpoint is configured, return null
|
||||||
|
URI logoutEndpoint = confService.getLogoutEndpoint();
|
||||||
|
if (logoutEndpoint == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
// Build the logout URI with appropriate parameters
|
||||||
|
UriBuilder logoutUriBuilder = UriBuilder.fromUri(logoutEndpoint);
|
||||||
|
|
||||||
|
// Add post_logout_redirect_uri parameter
|
||||||
|
logoutUriBuilder.queryParam("post_logout_redirect_uri",
|
||||||
|
confService.getPostLogoutRedirectURI());
|
||||||
|
|
||||||
|
// Add id_token_hint if available, otherwise add client_id
|
||||||
|
if (idToken != null && !idToken.isEmpty())
|
||||||
|
logoutUriBuilder.queryParam("id_token_hint", idToken);
|
||||||
|
else
|
||||||
|
logoutUriBuilder.queryParam("client_id", confService.getClientID());
|
||||||
|
|
||||||
|
return logoutUriBuilder.build();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void shutdown() {
|
public void shutdown() {
|
||||||
// Nothing to clean up
|
// Nothing to clean up
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+58
-1
@@ -217,7 +217,32 @@ public class ConfigurationService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() { return "openid-redirect-uri"; }
|
public String getName() { return "openid-redirect-uri"; }
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The logout endpoint (URI) of the OpenID service. If specified, users
|
||||||
|
* will be redirected to this endpoint when they log out, allowing them
|
||||||
|
* to log out from the OpenID provider as well.
|
||||||
|
*/
|
||||||
|
private static final URIGuacamoleProperty OPENID_LOGOUT_ENDPOINT =
|
||||||
|
new URIGuacamoleProperty() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() { return "openid-logout-endpoint"; }
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The URI that the OpenID service should redirect to after logout is
|
||||||
|
* complete. If not specified, the main redirect URI will be used.
|
||||||
|
*/
|
||||||
|
private static final URIGuacamoleProperty OPENID_POST_LOGOUT_REDIRECT_URI =
|
||||||
|
new URIGuacamoleProperty() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() { return "openid-post-logout-redirect-uri"; }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -429,4 +454,36 @@ public class ConfigurationService {
|
|||||||
return environment.getProperty(OPENID_MAX_NONCE_VALIDITY, DEFAULT_MAX_NONCE_VALIDITY);
|
return environment.getProperty(OPENID_MAX_NONCE_VALIDITY, DEFAULT_MAX_NONCE_VALIDITY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the logout endpoint (URI) of the OpenID service, as configured
|
||||||
|
* with guacamole.properties. If configured, users will be redirected to
|
||||||
|
* this endpoint when they log out from Guacamole.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* The logout endpoint of the OpenID service, as configured with
|
||||||
|
* guacamole.properties, or null if not configured.
|
||||||
|
*
|
||||||
|
* @throws GuacamoleException
|
||||||
|
* If guacamole.properties cannot be parsed.
|
||||||
|
*/
|
||||||
|
public URI getLogoutEndpoint() throws GuacamoleException {
|
||||||
|
return environment.getProperty(OPENID_LOGOUT_ENDPOINT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the URI that the OpenID service should redirect to after logout
|
||||||
|
* is complete, as configured with guacamole.properties. If not configured,
|
||||||
|
* the main redirect URI will be used.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* The post-logout redirect URI, as configured with
|
||||||
|
* guacamole.properties, or the main redirect URI if not specified.
|
||||||
|
*
|
||||||
|
* @throws GuacamoleException
|
||||||
|
* If guacamole.properties cannot be parsed.
|
||||||
|
*/
|
||||||
|
public URI getPostLogoutRedirectURI() throws GuacamoleException {
|
||||||
|
return environment.getProperty(OPENID_POST_LOGOUT_REDIRECT_URI, getRedirectURI());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+40
@@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The module for code implementing SSO using OpenID Connect.
|
||||||
|
*/
|
||||||
|
angular.module('guacSsoOpenid', []);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redirect to the SSO logout endpoint when the user logs out, allowing
|
||||||
|
* Single Logout to occur if configured.
|
||||||
|
*/
|
||||||
|
angular.module('guacSsoOpenid').run(['$rootScope', '$window',
|
||||||
|
function guacSsoOpenidLogout($rootScope, $window) {
|
||||||
|
|
||||||
|
// Redirect to SSO logout endpoint when user logs out
|
||||||
|
$rootScope.$on('guacLogout', function handleLogout() {
|
||||||
|
$window.location.href = 'api/ext/openid/logout';
|
||||||
|
});
|
||||||
|
|
||||||
|
}]);
|
||||||
|
|
||||||
|
// Ensure the guacSsoOpenid module is loaded along with the rest of the app
|
||||||
|
angular.module('index').requires.push('guacSsoOpenid');
|
||||||
Reference in new issue
Block a user