mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 05:07:41 +00:00
GUACAMOLE-1372: Merge support for signed SAML requests.
This commit is contained in:
@@ -126,6 +126,8 @@ public class AuthenticationSessionManager {
|
||||
* call to resume(). If authentication is never resumed, the session will
|
||||
* automatically be cleaned up after it ceases to be valid.
|
||||
*
|
||||
* This method will automatically generate a new identifier.
|
||||
*
|
||||
* @param session
|
||||
* The {@link AuthenticationSession} representing the in-progress SAML
|
||||
* authentication attempt.
|
||||
@@ -140,6 +142,27 @@ public class AuthenticationSessionManager {
|
||||
return identifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defers the Guacamole side of authentication for the user having the
|
||||
* given authentication session such that it may be later resumed through a
|
||||
* call to resume(). If authentication is never resumed, the session will
|
||||
* automatically be cleaned up after it ceases to be valid.
|
||||
*
|
||||
* This method accepts an externally generated ID, which should be a UUID
|
||||
* or similar unique identifier.
|
||||
*
|
||||
* @param session
|
||||
* The {@link AuthenticationSession} representing the in-progress SAML
|
||||
* authentication attempt.
|
||||
*
|
||||
* @param identifier
|
||||
* A unique and unpredictable string that may be used to represent the
|
||||
* given session when calling resume().
|
||||
*/
|
||||
public void defer(AuthenticationSession session, String identifier) {
|
||||
sessions.put(identifier, session);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shuts down the executor service that periodically removes all invalid
|
||||
* authentication sessions. This must be invoked when the SAML extension is
|
||||
|
@@ -21,7 +21,9 @@ package org.apache.guacamole.auth.saml.acs;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import com.onelogin.saml2.Auth;
|
||||
import com.onelogin.saml2.authn.AuthnRequest;
|
||||
import com.onelogin.saml2.authn.AuthnRequestParams;
|
||||
import com.onelogin.saml2.authn.SamlResponse;
|
||||
import com.onelogin.saml2.exception.SettingsException;
|
||||
import com.onelogin.saml2.exception.ValidationError;
|
||||
@@ -29,7 +31,6 @@ import com.onelogin.saml2.settings.Saml2Settings;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import javax.ws.rs.core.UriBuilder;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.xpath.XPathExpressionException;
|
||||
import org.apache.guacamole.GuacamoleException;
|
||||
@@ -57,6 +58,12 @@ public class SAMLService {
|
||||
@Inject
|
||||
private AuthenticationSessionManager sessionManager;
|
||||
|
||||
/**
|
||||
* Generator of arbitrary, unique, unpredictable identifiers.
|
||||
*/
|
||||
@Inject
|
||||
private IdentifierGenerator idGenerator;
|
||||
|
||||
/**
|
||||
* Creates a new SAML request, beginning the overall authentication flow
|
||||
* that will ultimately result in an asserted user identity if the user is
|
||||
@@ -75,20 +82,31 @@ public class SAMLService {
|
||||
public URI createRequest() throws GuacamoleException {
|
||||
|
||||
Saml2Settings samlSettings = confService.getSamlSettings();
|
||||
AuthnRequest samlReq = new AuthnRequest(samlSettings);
|
||||
|
||||
// Create a new authentication session to represent this attempt while
|
||||
// it is in progress
|
||||
AuthenticationSession session = new AuthenticationSession(samlReq.getId(),
|
||||
confService.getAuthenticationTimeout() * 60000L);
|
||||
|
||||
// Produce redirect for continuing the authentication process with
|
||||
// the SAML IdP
|
||||
try {
|
||||
return UriBuilder.fromUri(samlSettings.getIdpSingleSignOnServiceUrl().toURI())
|
||||
.queryParam("SAMLRequest", samlReq.getEncodedAuthnRequest())
|
||||
.queryParam("RelayState", sessionManager.defer(session))
|
||||
.build();
|
||||
Auth auth = new Auth(samlSettings, null, null);
|
||||
|
||||
// Generate a unique ID to use for the relay state
|
||||
String identifier = idGenerator.generateIdentifier();
|
||||
|
||||
// Create the request URL for the SAML IdP
|
||||
String requestUrl = auth.login(
|
||||
identifier,
|
||||
new AuthnRequestParams(false, false, true),
|
||||
true);
|
||||
|
||||
// Create a new authentication session to represent this attempt while
|
||||
// it is in progress, using the request ID that was just issued
|
||||
AuthenticationSession session = new AuthenticationSession(
|
||||
auth.getLastRequestId(),
|
||||
confService.getAuthenticationTimeout() * 60000L);
|
||||
|
||||
// Save the session with the unique relay state ID
|
||||
sessionManager.defer(session, identifier);
|
||||
|
||||
return new URI(requestUrl);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new GuacamoleServerException("SAML authentication request "
|
||||
@@ -99,6 +117,11 @@ public class SAMLService {
|
||||
+ "be generated due to an error in the URI syntax: "
|
||||
+ e.getMessage());
|
||||
}
|
||||
catch (SettingsException e) {
|
||||
throw new GuacamoleServerException("Error while attempting to sign "
|
||||
+ "request using provided private key / certificate: "
|
||||
+ e.getMessage(), e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@@ -493,6 +493,14 @@ public class ConfigurationService {
|
||||
samlSettings.setCompressRequest(getCompressRequest());
|
||||
samlSettings.setCompressResponse(getCompressResponse());
|
||||
|
||||
// Request that the SAML library sign everything that it can, if
|
||||
// both private key and certificate are specified
|
||||
if (privateKeyFile != null && certificateFile != null) {
|
||||
samlSettings.setAuthnRequestsSigned(true);
|
||||
samlSettings.setLogoutRequestSigned(true);
|
||||
samlSettings.setLogoutResponseSigned(true);
|
||||
}
|
||||
|
||||
return samlSettings;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user