GUACAMOLE-103: Use UriBuilder for syntax-aware URL construction, rather than simple String concatenation.
diff --git a/extensions/guacamole-auth-saml/src/main/java/org/apache/guacamole/auth/saml/AuthenticationProviderService.java b/extensions/guacamole-auth-saml/src/main/java/org/apache/guacamole/auth/saml/AuthenticationProviderService.java
index ddc6dbd..063f0dc 100644
--- a/extensions/guacamole-auth-saml/src/main/java/org/apache/guacamole/auth/saml/AuthenticationProviderService.java
+++ b/extensions/guacamole-auth-saml/src/main/java/org/apache/guacamole/auth/saml/AuthenticationProviderService.java
@@ -26,7 +26,6 @@
 import com.onelogin.saml2.exception.SettingsException;
 import com.onelogin.saml2.exception.ValidationError;
 import com.onelogin.saml2.settings.Saml2Settings;
-import com.onelogin.saml2.util.Util;
 import java.io.IOException;
 import java.net.URI;
 import java.net.URISyntaxException;
@@ -39,6 +38,7 @@
 import java.util.Map.Entry;
 import java.util.Set;
 import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.core.UriBuilder;
 import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.xpath.XPathExpressionException;
 import org.apache.guacamole.auth.saml.conf.ConfigurationService;
@@ -196,8 +196,9 @@
         AuthnRequest samlReq = new AuthnRequest(samlSettings);
         URI authUri;
         try {
-            authUri = new URI(samlSettings.getIdpSingleSignOnServiceUrl() + "?SAMLRequest=" +
-                    Util.urlEncoder(samlReq.getEncodedAuthnRequest()));
+            authUri = UriBuilder.fromUri(samlSettings.getIdpSingleSignOnServiceUrl().toURI())
+                    .queryParam("SAMLRequest", samlReq.getEncodedAuthnRequest())
+                    .build();
         }
         catch (IOException e) {
             logger.error("Error encoding authentication request to string: {}", e.getMessage());
diff --git a/extensions/guacamole-auth-saml/src/main/java/org/apache/guacamole/auth/saml/SAMLAuthenticationProviderResource.java b/extensions/guacamole-auth-saml/src/main/java/org/apache/guacamole/auth/saml/SAMLAuthenticationProviderResource.java
index 4a1e521..1b40494 100644
--- a/extensions/guacamole-auth-saml/src/main/java/org/apache/guacamole/auth/saml/SAMLAuthenticationProviderResource.java
+++ b/extensions/guacamole-auth-saml/src/main/java/org/apache/guacamole/auth/saml/SAMLAuthenticationProviderResource.java
@@ -26,7 +26,6 @@
 import com.onelogin.saml2.http.HttpRequest;
 import com.onelogin.saml2.servlet.ServletUtils;
 import com.onelogin.saml2.settings.Saml2Settings;
-import com.onelogin.saml2.util.Util;
 import java.io.IOException;
 import java.net.URI;
 import java.net.URISyntaxException;
@@ -39,6 +38,7 @@
 import javax.ws.rs.Path;
 import javax.ws.rs.POST;
 import javax.ws.rs.core.Context;
+import javax.ws.rs.core.UriBuilder;
 import javax.xml.bind.DatatypeConverter;
 import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.xpath.XPathExpressionException;
@@ -101,7 +101,7 @@
             @Context HttpServletRequest consumedRequest)
             throws GuacamoleException {
         
-        String guacBase = confService.getCallbackUrl().toString();
+        URI guacBase = confService.getCallbackUrl();
         Saml2Settings samlSettings = confService.getSamlSettings();
         try {
             HttpRequest request = ServletUtils
@@ -111,9 +111,9 @@
             
             String responseHash = hashSamlResponse(samlResponseString);
             samlResponseMap.putSamlResponse(responseHash, samlResponse);
-            return Response.seeOther(new URI(guacBase 
-                    + "?responseHash="
-                    + Util.urlEncoder(responseHash))
+            return Response.seeOther(UriBuilder.fromUri(guacBase)
+                    .queryParam("responseHash", responseHash)
+                    .build()
             ).build();
 
         }
@@ -132,9 +132,6 @@
         catch (SettingsException e) {
             throw new GuacamoleServerException("Settings exception processing SAML response.", e);
         }
-        catch (URISyntaxException e) {
-            throw new GuacamoleServerException("URI exception process SAML response.", e);
-        }
         catch (ValidationError e) {
             throw new GuacamoleServerException("Exception validating SAML response.", e);
         }
diff --git a/extensions/guacamole-auth-saml/src/main/java/org/apache/guacamole/auth/saml/conf/ConfigurationService.java b/extensions/guacamole-auth-saml/src/main/java/org/apache/guacamole/auth/saml/conf/ConfigurationService.java
index ca830cf..50627e3 100644
--- a/extensions/guacamole-auth-saml/src/main/java/org/apache/guacamole/auth/saml/conf/ConfigurationService.java
+++ b/extensions/guacamole-auth-saml/src/main/java/org/apache/guacamole/auth/saml/conf/ConfigurationService.java
@@ -27,6 +27,7 @@
 import java.net.URI;
 import java.util.HashMap;
 import java.util.Map;
+import javax.ws.rs.core.UriBuilder;
 import org.apache.guacamole.GuacamoleException;
 import org.apache.guacamole.GuacamoleServerException;
 import org.apache.guacamole.environment.Environment;
@@ -335,7 +336,7 @@
         samlMap.put(SettingsBuilder.SP_ENTITYID_PROPERTY_KEY,
                 getEntityId().toString());
         samlMap.put(SettingsBuilder.SP_ASSERTION_CONSUMER_SERVICE_URL_PROPERTY_KEY,
-                getCallbackUrl().toString() + "/api/ext/saml/callback");
+                UriBuilder.fromUri(getCallbackUrl()).path("api/ext/saml/callback").build().toString());
         
         SettingsBuilder samlBuilder = new SettingsBuilder();
         Saml2Settings samlSettings = samlBuilder.fromValues(samlMap).build();