GUACAMOLE-1266 SAML Single Logout
This commit is contained in:
1 parent
4763856847
commit
7c237334e7
5 files changed
+174
No files matched your search
@@ -36,6 +36,57 @@
|
|||||||
<relativePath>../../</relativePath>
|
<relativePath>../../</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
|
||||||
|
<!-- JS/CSS Minification Plugin -->
|
||||||
|
<plugin>
|
||||||
|
<groupId>com.github.buckelieg</groupId>
|
||||||
|
<artifactId>minify-maven-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>default-cli</id>
|
||||||
|
<configuration>
|
||||||
|
<charset>UTF-8</charset>
|
||||||
|
|
||||||
|
<webappSourceDir>${basedir}/src/main/resources</webappSourceDir>
|
||||||
|
<webappTargetDir>${project.build.directory}/classes</webappTargetDir>
|
||||||
|
|
||||||
|
<jsSourceDir>/</jsSourceDir>
|
||||||
|
<jsTargetDir>/</jsTargetDir>
|
||||||
|
<jsFinalFile>saml.js</jsFinalFile>
|
||||||
|
|
||||||
|
<jsSourceFiles>
|
||||||
|
<jsSourceFile>license.txt</jsSourceFile>
|
||||||
|
</jsSourceFiles>
|
||||||
|
|
||||||
|
<jsSourceIncludes>
|
||||||
|
<jsSourceInclude>**/*.js</jsSourceInclude>
|
||||||
|
</jsSourceIncludes>
|
||||||
|
|
||||||
|
<!-- Do not minify and include tests -->
|
||||||
|
<jsSourceExcludes>
|
||||||
|
<jsSourceExclude>**/*.test.js</jsSourceExclude>
|
||||||
|
</jsSourceExcludes>
|
||||||
|
<jsEngine>CLOSURE</jsEngine>
|
||||||
|
|
||||||
|
<!-- Disable warnings for JSDoc annotations -->
|
||||||
|
<closureWarningLevels>
|
||||||
|
<misplacedTypeAnnotation>OFF</misplacedTypeAnnotation>
|
||||||
|
<nonStandardJsDocs>OFF</nonStandardJsDocs>
|
||||||
|
</closureWarningLevels>
|
||||||
|
|
||||||
|
</configuration>
|
||||||
|
<goals>
|
||||||
|
<goal>minify</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
||||||
<!-- Guacamole Extension API -->
|
<!-- Guacamole Extension API -->
|
||||||
|
|||||||
+24
@@ -27,6 +27,8 @@ import java.util.Arrays;
|
|||||||
import org.apache.guacamole.auth.saml.user.SAMLAuthenticatedUser;
|
import org.apache.guacamole.auth.saml.user.SAMLAuthenticatedUser;
|
||||||
import org.apache.guacamole.GuacamoleException;
|
import org.apache.guacamole.GuacamoleException;
|
||||||
import org.apache.guacamole.auth.saml.acs.AssertedIdentity;
|
import org.apache.guacamole.auth.saml.acs.AssertedIdentity;
|
||||||
|
import org.apache.guacamole.auth.saml.conf.ConfigurationService;
|
||||||
|
import javax.ws.rs.core.UriBuilder;
|
||||||
import org.apache.guacamole.auth.saml.acs.SAMLAuthenticationSessionManager;
|
import org.apache.guacamole.auth.saml.acs.SAMLAuthenticationSessionManager;
|
||||||
import org.apache.guacamole.auth.saml.acs.SAMLService;
|
import org.apache.guacamole.auth.saml.acs.SAMLService;
|
||||||
import org.apache.guacamole.auth.sso.SSOAuthenticationProviderService;
|
import org.apache.guacamole.auth.sso.SSOAuthenticationProviderService;
|
||||||
@@ -68,6 +70,12 @@ public class AuthenticationProviderService implements SSOAuthenticationProviderS
|
|||||||
@Inject
|
@Inject
|
||||||
private SAMLService saml;
|
private SAMLService saml;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Service for retrieving SAML configuration information.
|
||||||
|
*/
|
||||||
|
@Inject
|
||||||
|
private ConfigurationService confService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the value of the session identifier associated with the given
|
* Return the value of the session identifier associated with the given
|
||||||
* credentials, or null if no session identifier is found in the
|
* credentials, or null if no session identifier is found in the
|
||||||
@@ -117,6 +125,22 @@ public class AuthenticationProviderService implements SSOAuthenticationProviderS
|
|||||||
return saml.createRequest();
|
return saml.createRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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 post-logout redirect
|
||||||
|
UriBuilder logoutUriBuilder = UriBuilder.fromUri(logoutEndpoint);
|
||||||
|
logoutUriBuilder.queryParam("RelayState",
|
||||||
|
confService.getPostLogoutRedirectURI());
|
||||||
|
|
||||||
|
return logoutUriBuilder.build();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void shutdown() {
|
public void shutdown() {
|
||||||
sessionManager.shutdown();
|
sessionManager.shutdown();
|
||||||
|
|||||||
+55
@@ -190,6 +190,30 @@ public class ConfigurationService {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The logout endpoint (URI) of the SAML IdP. When configured, users will
|
||||||
|
* be redirected to this endpoint when they log out of Guacamole.
|
||||||
|
*/
|
||||||
|
private static final URIGuacamoleProperty SAML_LOGOUT_ENDPOINT =
|
||||||
|
new URIGuacamoleProperty() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() { return "saml-logout-endpoint"; }
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The URI to redirect to after logout is complete. Defaults to the
|
||||||
|
* callback URL if not specified.
|
||||||
|
*/
|
||||||
|
private static final URIGuacamoleProperty SAML_POST_LOGOUT_REDIRECT_URI =
|
||||||
|
new URIGuacamoleProperty() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() { return "saml-post-logout-redirect-uri"; }
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Guacamole server environment.
|
* The Guacamole server environment.
|
||||||
*/
|
*/
|
||||||
@@ -390,6 +414,37 @@ public class ConfigurationService {
|
|||||||
return environment.getProperty(SAML_PRIVATE_KEY_PATH);
|
return environment.getProperty(SAML_PRIVATE_KEY_PATH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the logout endpoint (URI) of the SAML IdP. If not configured,
|
||||||
|
* null will be returned and logout will only end the Guacamole session.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* The logout endpoint of the SAML IdP, or null if not configured.
|
||||||
|
*
|
||||||
|
* @throws GuacamoleException
|
||||||
|
* If guacamole.properties cannot be parsed.
|
||||||
|
*/
|
||||||
|
public URI getLogoutEndpoint() throws GuacamoleException {
|
||||||
|
return environment.getProperty(SAML_LOGOUT_ENDPOINT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the URI to redirect to after logout is complete. If not
|
||||||
|
* configured, the callback URL will be used.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* The post-logout redirect URI.
|
||||||
|
*
|
||||||
|
* @throws GuacamoleException
|
||||||
|
* If guacamole.properties cannot be parsed.
|
||||||
|
*/
|
||||||
|
public URI getPostLogoutRedirectURI() throws GuacamoleException {
|
||||||
|
URI postLogoutUri = environment.getProperty(SAML_POST_LOGOUT_REDIRECT_URI);
|
||||||
|
if (postLogoutUri != null)
|
||||||
|
return postLogoutUri;
|
||||||
|
return getCallbackUrl();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the contents of a small file, such as a private key or certificate into
|
* Returns the contents of a small file, such as a private key or certificate into
|
||||||
* a String. If the file does not exist, or cannot be read for any reason, an exception
|
* a String. If the file does not exist, or cannot be read for any reason, an exception
|
||||||
|
|||||||
+4
@@ -34,6 +34,10 @@
|
|||||||
"translations/ru.json",
|
"translations/ru.json",
|
||||||
"translations/tr.json",
|
"translations/tr.json",
|
||||||
"translations/zh.json"
|
"translations/zh.json"
|
||||||
|
],
|
||||||
|
|
||||||
|
"js" : [
|
||||||
|
"saml.min.js"
|
||||||
]
|
]
|
||||||
|
|
||||||
}
|
}
|
||||||
+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 SAML.
|
||||||
|
*/
|
||||||
|
angular.module('guacSsoSaml', []);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redirect to the SSO logout endpoint when the user logs out, allowing
|
||||||
|
* Single Logout to occur if configured.
|
||||||
|
*/
|
||||||
|
angular.module('guacSsoSaml').run(['$rootScope', '$window',
|
||||||
|
function guacSsoSamlLogout($rootScope, $window) {
|
||||||
|
|
||||||
|
// Redirect to SSO logout endpoint when user logs out
|
||||||
|
$rootScope.$on('guacLogout', function handleLogout() {
|
||||||
|
$window.location.href = 'api/ext/saml/logout';
|
||||||
|
});
|
||||||
|
|
||||||
|
}]);
|
||||||
|
|
||||||
|
// Ensure the guacSsoSaml module is loaded along with the rest of the app
|
||||||
|
angular.module('index').requires.push('guacSsoSaml');
|
||||||
Reference in new issue
Block a user