|
11 | 11 | import java.util.LinkedHashMap; |
12 | 12 | import java.util.List; |
13 | 13 | import java.util.Map; |
| 14 | +import java.util.Objects; |
| 15 | +import java.util.Scanner; |
14 | 16 |
|
15 | 17 | import javax.servlet.http.HttpServletRequest; |
16 | 18 | import javax.servlet.http.HttpServletResponse; |
| 19 | +import javax.xml.parsers.ParserConfigurationException; |
| 20 | +import javax.xml.xpath.XPathExpressionException; |
17 | 21 |
|
18 | 22 | import org.apache.commons.lang3.StringUtils; |
| 23 | +import org.apache.xml.security.exceptions.XMLSecurityException; |
19 | 24 | import org.joda.time.DateTime; |
20 | 25 | import org.joda.time.Instant; |
21 | 26 | import org.slf4j.Logger; |
|
34 | 39 | import com.onelogin.saml2.settings.SettingsBuilder; |
35 | 40 | import com.onelogin.saml2.util.Constants; |
36 | 41 | import com.onelogin.saml2.util.Util; |
| 42 | +import org.xml.sax.SAXException; |
37 | 43 |
|
38 | 44 | /** |
39 | 45 | * Main class of OneLogin's Java Toolkit. |
@@ -139,6 +145,8 @@ public class Auth { |
139 | 145 | */ |
140 | 146 | private String lastResponse; |
141 | 147 |
|
| 148 | + private String requestPostBindingHTML; |
| 149 | + |
142 | 150 | /** |
143 | 151 | * Initializes the SP SAML instance. |
144 | 152 | * |
@@ -224,6 +232,12 @@ public Auth(Saml2Settings settings, HttpServletRequest request, HttpServletRespo |
224 | 232 | throw new SettingsException(errorMsg, SettingsException.SETTINGS_INVALID); |
225 | 233 | } |
226 | 234 | LOGGER.debug("Settings validated"); |
| 235 | + |
| 236 | + |
| 237 | + if (Objects.equals(Constants.BINDING_HTTP_POST, settings.getIdpSingleSignOnServiceBinding())) { |
| 238 | + Scanner s = new Scanner(getClass().getClassLoader().getResourceAsStream("request-post-binding.html")).useDelimiter("\\A"); |
| 239 | + this.requestPostBindingHTML = s.hasNext() ? s.next() : ""; |
| 240 | + } |
227 | 241 | } |
228 | 242 |
|
229 | 243 | /** |
@@ -262,37 +276,77 @@ public String login(String returnTo, Boolean forceAuthn, Boolean isPassive, Bool |
262 | 276 |
|
263 | 277 | AuthnRequest authnRequest = new AuthnRequest(settings, forceAuthn, isPassive, setNameIdPolicy); |
264 | 278 |
|
265 | | - String samlRequest = authnRequest.getEncodedAuthnRequest(); |
266 | | - |
267 | | - parameters.put("SAMLRequest", samlRequest); |
268 | | - |
269 | 279 | String relayState; |
270 | 280 | if (returnTo == null) { |
271 | 281 | relayState = ServletUtils.getSelfRoutedURLNoQuery(request); |
272 | 282 | } else { |
273 | 283 | relayState = returnTo; |
274 | 284 | } |
275 | 285 |
|
276 | | - if (!relayState.isEmpty()) { |
277 | | - parameters.put("RelayState", relayState); |
278 | | - } |
| 286 | + if (Objects.equals(Constants.BINDING_HTTP_REDIRECT, settings.getIdpSingleSignOnServiceBinding())) { |
| 287 | + String samlRequest = authnRequest.getEncodedAuthnRequest(); |
279 | 288 |
|
280 | | - if (settings.getAuthnRequestsSigned()) { |
281 | | - String sigAlg = settings.getSignatureAlgorithm(); |
282 | | - String signature = this.buildRequestSignature(samlRequest, relayState, sigAlg); |
| 289 | + parameters.put("SAMLRequest", samlRequest); |
283 | 290 |
|
284 | | - parameters.put("SigAlg", sigAlg); |
285 | | - parameters.put("Signature", signature); |
286 | | - } |
| 291 | + if (!relayState.isEmpty()) { |
| 292 | + parameters.put("RelayState", relayState); |
| 293 | + } |
287 | 294 |
|
288 | | - String ssoUrl = getSSOurl(); |
289 | | - lastRequestId = authnRequest.getId(); |
290 | | - lastRequest = authnRequest.getAuthnRequestXml(); |
| 295 | + if (settings.getAuthnRequestsSigned()) { |
| 296 | + String sigAlg = settings.getSignatureAlgorithm(); |
| 297 | + String signature = this.buildRequestSignature(samlRequest, relayState, sigAlg); |
291 | 298 |
|
292 | | - if (!stay) { |
293 | | - LOGGER.debug("AuthNRequest sent to " + ssoUrl + " --> " + samlRequest); |
| 299 | + parameters.put("SigAlg", sigAlg); |
| 300 | + parameters.put("Signature", signature); |
| 301 | + } |
| 302 | + |
| 303 | + String ssoUrl = getSSOurl(); |
| 304 | + lastRequestId = authnRequest.getId(); |
| 305 | + lastRequest = authnRequest.getAuthnRequestXml(); |
| 306 | + |
| 307 | + if (!stay) { |
| 308 | + LOGGER.debug("AuthNRequest sent to " + ssoUrl + " --> " + samlRequest); |
| 309 | + } |
| 310 | + return ServletUtils.sendRedirect(response, ssoUrl, parameters, stay); |
| 311 | + } else if (Objects.equals(Constants.BINDING_HTTP_POST, settings.getIdpSingleSignOnServiceBinding())) { |
| 312 | + String requestPostBinding = null; |
| 313 | + |
| 314 | + try { |
| 315 | + String authnRequestXML; |
| 316 | + |
| 317 | + if (settings.getAuthnRequestsSigned()) { |
| 318 | + authnRequestXML = Util.addSign( |
| 319 | + Util.convertStringToDocument(authnRequest.getAuthnRequestXml()), |
| 320 | + settings.getSPkey(), |
| 321 | + settings.getSPcert(), |
| 322 | + settings.getSignatureAlgorithm(), |
| 323 | + Constants.C14NEXC); |
| 324 | + |
| 325 | + LOGGER.debug("Signed XML: {}", authnRequestXML); |
| 326 | + } else { |
| 327 | + authnRequestXML = authnRequest.getEncodedAuthnRequest(false); |
| 328 | + } |
| 329 | + |
| 330 | + requestPostBinding = String.format( |
| 331 | + this.requestPostBindingHTML, |
| 332 | + settings.getOrganization().getOrgDisplayName(), |
| 333 | + settings.getIdpSingleSignOnServiceUrl(), |
| 334 | + Util.base64encoder(authnRequestXML), |
| 335 | + relayState |
| 336 | + ); |
| 337 | + |
| 338 | + if (!stay) { |
| 339 | + ServletUtils.respondWithContentString(response, requestPostBinding, "text/html; charset=utf-8"); |
| 340 | + } |
| 341 | + |
| 342 | + } catch (Exception e) { |
| 343 | + LOGGER.error("Error {}", e.getMessage(), e); |
| 344 | + } |
| 345 | + |
| 346 | + return requestPostBinding; |
| 347 | + } else { |
| 348 | + throw new SettingsException("Unsupported SSO binding: " + settings.getIdpSingleSignOnServiceBinding(), SettingsException.UNSUPPORTED_BINDING); |
294 | 349 | } |
295 | | - return ServletUtils.sendRedirect(response, ssoUrl, parameters, stay); |
296 | 350 | } |
297 | 351 |
|
298 | 352 | /** |
|
0 commit comments