mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 05:07:41 +00:00
GUACAMOLE-1372: Modify usage of SAML library to allow signed requests.
This commit is contained in:
@@ -126,6 +126,8 @@ public class AuthenticationSessionManager {
|
|||||||
* call to resume(). If authentication is never resumed, the session will
|
* call to resume(). If authentication is never resumed, the session will
|
||||||
* automatically be cleaned up after it ceases to be valid.
|
* automatically be cleaned up after it ceases to be valid.
|
||||||
*
|
*
|
||||||
|
* This method will automatically generate a new identifier.
|
||||||
|
*
|
||||||
* @param session
|
* @param session
|
||||||
* The {@link AuthenticationSession} representing the in-progress SAML
|
* The {@link AuthenticationSession} representing the in-progress SAML
|
||||||
* authentication attempt.
|
* authentication attempt.
|
||||||
@@ -140,6 +142,27 @@ public class AuthenticationSessionManager {
|
|||||||
return identifier;
|
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
|
* Shuts down the executor service that periodically removes all invalid
|
||||||
* authentication sessions. This must be invoked when the SAML extension is
|
* 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.Inject;
|
||||||
import com.google.inject.Singleton;
|
import com.google.inject.Singleton;
|
||||||
|
import com.onelogin.saml2.Auth;
|
||||||
import com.onelogin.saml2.authn.AuthnRequest;
|
import com.onelogin.saml2.authn.AuthnRequest;
|
||||||
|
import com.onelogin.saml2.authn.AuthnRequestParams;
|
||||||
import com.onelogin.saml2.authn.SamlResponse;
|
import com.onelogin.saml2.authn.SamlResponse;
|
||||||
import com.onelogin.saml2.exception.SettingsException;
|
import com.onelogin.saml2.exception.SettingsException;
|
||||||
import com.onelogin.saml2.exception.ValidationError;
|
import com.onelogin.saml2.exception.ValidationError;
|
||||||
@@ -29,7 +31,6 @@ import com.onelogin.saml2.settings.Saml2Settings;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import javax.ws.rs.core.UriBuilder;
|
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
import javax.xml.xpath.XPathExpressionException;
|
import javax.xml.xpath.XPathExpressionException;
|
||||||
import org.apache.guacamole.GuacamoleException;
|
import org.apache.guacamole.GuacamoleException;
|
||||||
@@ -57,6 +58,12 @@ public class SAMLService {
|
|||||||
@Inject
|
@Inject
|
||||||
private AuthenticationSessionManager sessionManager;
|
private AuthenticationSessionManager sessionManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generator of arbitrary, unique, unpredictable identifiers.
|
||||||
|
*/
|
||||||
|
@Inject
|
||||||
|
private IdentifierGenerator idGenerator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new SAML request, beginning the overall authentication flow
|
* Creates a new SAML request, beginning the overall authentication flow
|
||||||
* that will ultimately result in an asserted user identity if the user is
|
* 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 {
|
public URI createRequest() throws GuacamoleException {
|
||||||
|
|
||||||
Saml2Settings samlSettings = confService.getSamlSettings();
|
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
|
// Produce redirect for continuing the authentication process with
|
||||||
// the SAML IdP
|
// the SAML IdP
|
||||||
try {
|
try {
|
||||||
return UriBuilder.fromUri(samlSettings.getIdpSingleSignOnServiceUrl().toURI())
|
Auth auth = new Auth(samlSettings, null, null);
|
||||||
.queryParam("SAMLRequest", samlReq.getEncodedAuthnRequest())
|
|
||||||
.queryParam("RelayState", sessionManager.defer(session))
|
// Generate a unique ID to use for the relay state
|
||||||
.build();
|
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) {
|
catch (IOException e) {
|
||||||
throw new GuacamoleServerException("SAML authentication request "
|
throw new GuacamoleServerException("SAML authentication request "
|
||||||
@@ -99,6 +117,11 @@ public class SAMLService {
|
|||||||
+ "be generated due to an error in the URI syntax: "
|
+ "be generated due to an error in the URI syntax: "
|
||||||
+ e.getMessage());
|
+ 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.setCompressRequest(getCompressRequest());
|
||||||
samlSettings.setCompressResponse(getCompressResponse());
|
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;
|
return samlSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user