If the problem here is that the vendor can't generate a request, but also
can't ignore the InResponseTo value (since it wouldn't match a request that
they generated), there's a SAML extension defined for that called a "third
party request" that indicates to the IdP that the system sending the request
isn't actually the SP to respond to. It's an extension element called
"RespondTo", IIRC, that just tells it to send an unsolicited response to the
SP named in the element.
I just looked, it's actually a committee spec, so it's basically one step
short of standard (the step being that 3 implementations are needed).
http://wiki.oasis-open.org/security/ProtocolExtThirdParty
So if you were going to file a request to support something, that would be
the feature to reference.
This was one of the use cases, allowing an outside request (which gives the
IdP more information about how to respond), but avoiding InResponseTo.
-- Scott
My SP never looks at InResponseTo because it has nothing to compare it to,
so I will say if you patched it to simply remove that code in your IdP it
won't break anything I wrote. I can't speak for other SPs of course.
The effort it would take to add the option you described is not
significantly different than the effort to support the extension. With
either one, you would either have to do it, or file a request, but I
wouldn't be the one doing it, nor is there an IdP release likely very soon.
So the only short term fix is adding something on your own (or finding
somebody to help), or removing that line of code.
-- Scott
--
SWITCH
Serving Swiss Universities
--------------------------
Chad La Joie, Software Engineer, Net Services
Werdstrasse 2, P.O. Box, 8021 Zürich, Switzerland
phone +41 44 268 15 75, fax +41 44 268 15 68
chad....@switch.ch, http://www.switch.ch
Hi -
We've been following your thread on the shib-users list and was interested in trying out your patch. I thought I'd be able to run something like
patch -p1 -i RespondTo.patch
inside the unarchived shibboleth-identityprovider-2.1.2-bin.tar.gz (shibboleth-identityprovider-2.1.2) directory, then rerun the install.sh script to deploy the patched 2.1 IdP. I was not able to find AbstractSAML2ProfileHandler.java on my system to patch against, am I going about this the right way?
I also wanted to clarify that this patch would modify the IdP in such a way that it would not include the InResponseTo attribute in any unsolicited responses, but would include this attribute in any solicited responses? Correct?
Thanks,
R.
+++ Joseph Valerio <joseph....@yale.edu> [09/06/22 08:00]:
> <%@page import="org.opensaml.xml.*"%>
> <%@page import="org.opensaml.saml2.common.*" %>
> <%@page import="org.opensaml.saml2.common.impl.*" %>
> <%@page import="java.util.UUID"%>
> <%@page import="org.opensaml.saml2.core.*"%>
> <%@page import="org.opensaml.saml2.core.impl.*"%>
> <%@page import="org.opensaml.xml.Configuration"%>
> <%@page import="org.opensaml.xml.XMLObjectBuilderFactory"%>
> <%@page import="org.joda.time.DateTime"%>
> <%@page import="org.opensaml.xml.io.MarshallingException"%>
> <%@page import="org.opensaml.xml.util.XMLHelper"%>
> <%@page import="org.opensaml.saml2.core.impl.AuthnRequestMarshaller"%>
> <%@page import="org.w3c.dom.Element"%>
> <%@page import="org.opensaml.xml.util.Base64" %>
> <%@page import="org.opensaml.samlext.samlpthrpty.*" %>
> <%@page import="org.opensaml.samlext.samlpthrpty.impl.*" %>
> <html>
> <%
> String SAML_POST_SSO_CONTEXT = "/idp/profile/SAML2/POST/SSO";
> String PROTOCOL_BINDING = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST";
>
> String entityIdParam = request.getParameter("entityId");
> String acsUrlParam = request.getParameter("acsUrl");
> String relayStateParam = request.getParameter("relayState");
>
> String base64EncodedSamlRequest = null;
> String samlRequest = null;
>
> try {
> if(entityIdParam == null)
> throw new RuntimeException("entityId is a required parameter.");
> if(acsUrlParam == null)
> throw new RuntimeException("acsUrl is a required parameter.");
>
> XMLObjectBuilderFactory builderFactory = Configuration.getBuilderFactory();
>
> AuthnRequestBuilder authnRequestBuilder = (AuthnRequestBuilder) builderFactory.getBuilder(AuthnRequest.DEFAULT_ELEMENT_NAME);
> IssuerBuilder issuerBuilder = (IssuerBuilder) builderFactory.getBuilder(Issuer.DEFAULT_ELEMENT_NAME);
> NameIDPolicyBuilder nipBuilder = (NameIDPolicyBuilder) builderFactory.getBuilder(NameIDPolicy.DEFAULT_ELEMENT_NAME);
> RespondToBuilder rtBuilder = (RespondToBuilder) builderFactory.getBuilder(RespondTo.DEFAULT_ELEMENT_NAME);
> ExtensionsBuilder exBuilder = new ExtensionsBuilder();
>
> AuthnRequest authnReq = authnRequestBuilder.buildObject();
> authnReq.setAssertionConsumerServiceURL(acsUrlParam);
> authnReq.setID(UUID.randomUUID().toString());
> authnReq.setDestination(request.getScheme() + "://" + request.getServerName() + SAML_POST_SSO_CONTEXT);
> authnReq.setIssueInstant(new DateTime());
> authnReq.setProtocolBinding(PROTOCOL_BINDING);
>
> Issuer issuer = issuerBuilder.buildObject();
> issuer.setValue(entityIdParam);
> authnReq.setIssuer(issuer);
>
> Extensions exs = exBuilder.buildObject();
> RespondTo rt = rtBuilder.buildObject();
>
> exs.getUnknownXMLObjects().add(rt);
>
> authnReq.setExtensions(exs);
>
> NameIDPolicy nip = nipBuilder.buildObject();
> nip.setAllowCreate(true);
> authnReq.setNameIDPolicy(nip);
>
> AuthnRequestMarshaller m = new AuthnRequestMarshaller();
> Element elem = m.marshall(authnReq);
> samlRequest = XMLHelper.nodeToString(elem);
> base64EncodedSamlRequest = Base64.encodeBytes(samlRequest.getBytes());
>
> %>
> <body onload="document.forms[0].submit()">
> <noscript>
> <p>
> <strong>Note:</strong> Since your browser does not support JavaScript,
> you must press the Continue button once to proceed.
> </p>
> </noscript>
> <form method="post" action="<%=SAML_POST_SSO_CONTEXT%>">
> <input type="hidden" name="SAMLRequest" value="<%=base64EncodedSamlRequest %>" />
> <% if (relayStateParam != null) { %>
> <input type="hidden" name="RelayState" value="<%=relayStateParam %>" />
> <% } %>
> <noscript>
> <div>
> <input type="submit" value="Continue"/>
> </div>
> </noscript>
> <!--
> <%=samlRequest %>
> -->
> </form>
> </body>
> <%
> } catch (Exception e) {
> %>
> <head>
> <style type="text/css">
> .txt {
> font-family: Verdana, Arial, Helvetica, sans-serif;
> font-size: 12px;
> white-space: nowrap;
> }
> .hdr {
> font-family: Verdana, Arial, Helvetica, sans-serif;
> font-size: 16px;
> font-weight: bold;
> white-space: nowrap;
> }
> .code{
> border-width: 1px 1px 1px 1px;
> border-style: dashed;
> border-color:blue;
> background-color: lightgrey;
> width: 700px;
> height: 300px;
> overflow: auto;
> padding: 5px;
> display: none;
> }
> </style>
> <script language="JavaScript">
> function toggle(obj) {
> var el = document.getElementById(obj);
> el.style.display = (el.style.display != 'none' ? 'none' : '' );
> }
> </script>
> </head>
> <body class="txt">
> <span class="hdr">Error during IdP Initiated Post SSO attempt</span><br /><br />
> <strong>Error Message:</strong> <%=e.getMessage()%><br />
> <br />
> <table>
> <tr>
> <td colspan="4"><span class="hdr">Usage:</span></td>
> </tr>
> <tr>
> <td width="15" />
> <td>Request parameter <strong>entityId</strong> is required.</td>
> <td width="15" />
> <td><small>Current Value: <strong><%=entityIdParam == null ? "<null>" : entityIdParam %></strong></small></td>
> </tr>
> <tr>
> <td width="15" />
> <td>Request parameter <strong>acsUrl</strong> is required.</td>
> <td width="15" />
> <td><small>Current Value: <strong><%=acsUrlParam == null ? "<null>" : acsUrlParam%></strong></small></td>
> </tr>
> <tr>
> <td width="15" />
> <td>Request parameter <strong>relayState</strong> is optional.</td>
> <td width="15" />
> <td><small>Current Value: <strong><%=relayStateParam == null ? "<null>" : relayStateParam%></strong></small></td>
> </tr>
> </table>
> <br />
> <br />
> <strong><a href="javascript:toggle('exception')">Error Detail</a></strong>
> <div id="exception" style="border-width: 1px 1px 1px 1px;
> border-style: dashed;
> border-color:blue;
> background-color: lightgrey;
> width: 700px;
> height: 300px;
> overflow: auto;
> padding: 5px;
> display: none;">
> <pre>
> <%
> e.printStackTrace(new java.io.PrintWriter(out));
> %>
> </pre>
> </div>
> </body>
> <%
> }
> %>
> </html>
>
--
Redmond Militante NSIT/NBS The University of Chicago
PGP Public Key: <http://home.uchicago.edu/~rjm/pubkey.asc>
Redmond Militante wrote:
> inside the unarchived shibboleth-identityprovider-2.1.2-bin.tar.gz (shibboleth-identityprovider-2.1.2) directory, then rerun the install.sh script to deploy the patched 2.1 IdP. I was not able to find AbstractSAML2ProfileHandler.java on my system to patch against, am I going about this the right way?
That's the binary release of the IdP it wouldn't contain the source
files. To see how to build the IdP from source refer to the wiki.
Formally, SAML 2 assumes that IdP-initiated SSO implies a defaulted resource
URL at the SP. Informally, people still throw it into RelayState and ignore
the 80-byte limit, and most SPs, mine included, handle that.
-- Scott
Ramm wrote:
>
> tried AbstractSAML2ProfileHandler.java.patch, I built the IDP from source
> (mvn package). Rebuild idp.war and deployed. Still see 'inResponseTo'
> attribute in XML
>
--
View this message in context: http://n2.nabble.com/Idp-Initiated-POST-SSO-tp3122153p3977104.html
But I tried this patch against idp 2.1.5, is it matters ? Ramm wrote:tried AbstractSAML2ProfileHandler.java.patch, I built the IDP from source (mvn package). Rebuild idp.war and deployed. Still see 'inResponseTo' attribute in XML