I wish to confirm that RelayState is required for a valid signed SAML logout request.
We have federated Microsoft's ADFS 2012 R2 with Oracle's Identity Federation where ADFS is the SP and OIF is the IdP. As a basis, we followed Integrating ADFS 2.0/3.0 SP with OIF IdP.
Everything works, except logout. We have another SP doing a logout and working with OIF. One difference we've found is that ADFS is not sending a RelayState parameter with its signed logout request, but the other SP is. I've been using SAMLTool's Validate Logout Req, where I input the following:
SAML Logout Request
EntityId of the source
Target URL, Destination of the Logout Request
SigAlg
Signature of the SAML Logout Request
X.509 cert of the source (to check Signature)
Ignore timing issues: checked
That then gives me the error:
In order to check Signature you must provide the RelayState parameter and the X.509 cert
If I input RelayState along with my other values in SAMLTool's Validate Logout Req then it reports back that my signed logout request is valid.
In the case of ADFS, because it does not have a RelayState parameter, I cannnot get SAMLTool's Validate Logout Req to say that a logout from ADFS is valid.
All that said, I cannot find anywhere in the SAML spec that says RelayState is required for a signed logout request. Can anyone confirm that it is required and back it up with documentation?
The LogoutRequest message would not have a reference to the RelayState parameter (as the other post suggests) but it is part of the so-called binding that is used to convey messages between SAML parties. Assuming that the Logout uses the HTTP-Redirect, HTTP-POST or Artifact binding, the spec allows for the sender to include a RelayState parameter and the receiver must then return that same RelayState parameter as a part of the response (as a way for the sender to keep state).
See section 3.4.3 RelayState of the SAML bindings document: https://docs.oasis-open.org/security/saml/v2.0/saml-bindings-2.0-os.pdf for the HTTP-Redirect binding:
3.4.3 RelayState
RelayState data MAY be included with a SAML protocol message transmitted with
this binding. The value MUST NOT exceed 80
bytes in length and SHOULD be integrity protected by the entity
creating the message independent of any other protections that may or
may not exist during message transmission. Signing is not realistic
given the space limitation, but because the value is exposed to
third-party tampering, the entity SHOULD ensure that the value has not
been tampered with by using a checksum, a pseudo-random value, or
similar means. If a SAML request message is accompanied by RelayState
data, then the SAML responder MUST return its SAML protocol response
using a binding that also supports a RelayState mechanism, and it MUST
place the exact data it received with the request into the
corresponding RelayState parameter in the response. If no such value
is included with a SAML request message, or if the SAML response
message is being generated without a corresponding request, then the
SAML responder MAY include RelayState data to be interpreted by the
recipient based on the use of a profile or prior agreement between the
parties
For the other bindings a similar section exists. So as #nzpcmad says: it's not mandatory to include it in a request.
Reading SAMLv2 core spec "Single Logout Protocol" XML schema for the SAML LogoutRequestType
<element name="LogoutRequest" type="samlp:LogoutRequestType" />
<complexType name="LogoutRequestType">
<complexContent>
<extension base="samlp:RequestAbstractType">
<sequence>
<choice>
<element ref="saml:BaseID" />
<element ref="saml:NameID" />
<element ref="saml:EncryptedID" />
</choice>
<element ref="samlp:SessionIndex" minOccurs="0" maxOccurs="unbounded" />
</sequence>
<attribute name="Reason" type="string" use="optional" />
<attribute name="NotOnOrAfter" type="dateTime" use="optional" />
</extension>
</complexContent>
</complexType>
<element name="SessionIndex" type="string" />
does not mention the RelayState Element. The "Single Logout Profile" in the SAMLv2 profile spec does also not mention RelayState.
I would say this suggests that RelayState (which is a request parameter, so can only be used in a front-channel binding) is not mandatory.
Related
I just start work with SSO Saml and have some confuses that would like to clear.
- If I have to encode AuthnRequest with three mechanisms Deflate encode, Base64 encode, URL encodes. Do I have to use HTTP-Redirect to send message request?
- I refer to https://docs.oasis-open.org/security/saml/v2.0/saml-bindings-2.0-os.pdf page 16 for HTTP-Redirect Biding.
- If I using HTTP-Redirect Biding. Do I have to provide all 4 parameters SAMLRequest=value&RelayState=value&SigAlg=value&Signature=value or just two parameters SAMLRequest=value&RelayState=value I already have enough condition to send request to IdP.
If I have to encode AuthnRequest with three mechanisms Deflate encode,
Base64 encode, URL encodes. Do I have to use HTTP-Redirect to send
message request? - I refer to
https://docs.oasis-open.org/security/saml/v2.0/saml-bindings-2.0-os.pdf
page 16 for HTTP-Redirect Biding. - If I using HTTP-Redirect Biding.
Yes, thats the requirement because in HTTP-Redirect you send the request as URL parameter hence need to minimize it in length/size.
Do I have to provide all 4 parameters
SAMLRequest=value&RelayState=value&SigAlg=value&Signature=value or
just two parameters SAMLRequest=value&RelayState=value I already have
enough condition to send request to IdP.
That depends on what is require by IDP but SAMLRequest is mandatory AFAIK.
I want a link on my login page that says "Log in with [identity provider]". For ssocircle, apparently the login link is
https://idp.ssocircle.com/sso/idpssoinit?metaAlias=%2Fpublicidp
But this link isn't located anywhere in the XML used to configure it. The IdP XML contains the following:
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://idp.ssocircle.com:443/sso/SSORedirect/metaAlias/publicidp"/>
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://idp.ssocircle.com:443/sso/SSOPOST/metaAlias/publicidp"/>
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://idp.ssocircle.com:443/sso/SSOSoap/metaAlias/publicidp"/>
Is it not possible to build the URL from these? Do I need to add a configuration for every IdP that includes asking for the login URL as well as the XML?
Unfortunately the URL that you call on the IDP is out of scope for SAML.
SAML only specify that it is possible for the IDP to start the authentication itself, not what triggers it to start. This is why it is not present in metadata
For the use case you describe you should use Service Provider initiated SSO. In that case the URL that will be used to send the AuthnRequest to is defined in the metadata XML that you mentioned.
But you end up with a logic in your own application which must generate the correct AuthnRequest. But that URL is under your control ...
Image from the spec describes the SP initiated flow:
For my project I am required to display the encrypted as well as decrypted version of the SAML response to the user.
Currently the Spring SAML sample app displays the Encrypted (i.e. original) SAML response, but I am not sure how to show the same response with all elements (NameID, assertions, and other elements) decrypted.
I know that the Spring SAML sample app displays the assertions in a table format, but I am required to display the entire 'decrypted' XML SAML response with all the tags and attributes.
Note I am working the SP part and the IDP is configured to send encrypted SAML responses with encrypted attributes and NameIDs.
Any help is appreciated.
Part 9.5 of the manual should help you.
9.5 Authentication assertion
Assertion used to authenticate user is stored in the SAMLCredential
object under property authenticationAssertion. By default the original
content (DOM) of the assertion is discarded and system only keeps an
unmarshalled version which might slightly differ from the original,
e.g. in white-spaces. In order to instruct Spring SAML to keep the
assertion in the original form (keep its DOM) set property releaseDOM
to false on bean WebSSOProfileConsumerImpl.
Assertion can be serialized to String using the following call:
XMLHelper.nodeToString(SAMLUtil.marshallMessage(credential.getAuthenticationAssertion()))
I am implementing SAML2.0 ServiceProvider in java using spring-security-saml-sample code. After successful login response gets redirect to root path(welcome file) of application.How to redirect it to any controller ?
Thanks,
Tejas
You can customize URL to which user gets redirected after successful authentication by changing bean successRedirectHandler, for example to:
<bean id="successRedirectHandler"
class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
<property name="defaultTargetUrl" value="/myControllerURL"/>
</bean>
If you're looking for the general way to maintain state through the login process, SAML2 is expected to preserve the RelayState variable (pass it alongside the SAMLRequest). Put whatever you'd like in it. I like base64'd json.
I am trying to compose a SAML2 AuthnRequest for OpenAM. I have a URL that I can perform a get against that works, but am having problems composing this into the XHTML post form.
The working URL with query string is
http://internal.authhost.com:8080/opensso/idpssoinit?NameIDFormat=urn:oasis:names:tc:SAML:2.0:nameid-format:transient&metaAlias=%2FMYRealm%2Fidp&spEntityID=https%3A%2F%2Fsaml.salesforce.com&binding=urn%3Aoasis%3Anames%3Atc%3ASAML%3A2.0%3Abindings%3AHTTP-POST&RelayState=webj_captureCustomerDetails
My html form looks like:
<form action="http://internal.authhost.com:8080/opensso/idpssoinit" method="post" target="new">
<input type="text" name="SAMLRequest" value="PHNhbWxwOkF1dGhuUmV..."></input>
<input type="text" name="RelayState" value="webj_captureCustomerDetails"></input>
<input type="submit"/>
</form>
with the value of SAMLRequest being the Base 64 encoded representation of
<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
ID="_d7607d551380ac97853a6ff4907c4ef01219be97dd" Version="2.0"
IssueInstant="2008-05-27T07:46:06Z" ForceAuthn="true" IsPassive="false"
ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
AssertionConsumerServiceURL="https://cs4.salesforce.com/?saml=lkjhkljhkljhkjhlkjh"
ProviderName="https://saml.salesforce.com">
<saml:Issuer>https://saml.salesforce.com</saml:Issuer>
<samlp:NameIDPolicy Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient"
AllowCreate="true"/>
</samlp:AuthnRequest>
Issuing this form results in an error message from OpenAM stating "Service Provider ID is null"
I can immediately see that the XML does not contain the metaAlias=/MYRealm/idp argument, but the message suggests that it cannot find the spEntityID=https://saml.salesforce.com argument either.
Please advise on where these two properties (metaAlias and spEntityID) need to be specified in the XML.
A link to somewhere specifying how OpenAM COT / IdP configuration maps against SAML AuthnRequest message would also be appreciated.
Problem was that I was accessing the wrong URL, should have been hitting the spssoinit as it was Service Provider intitated SSO