Is SP signing certificate mandatory in setting up trust - saml-2.0

I have a basic question on setting up trust between a SP and IDP.
Usually a two way trust is required when we setup an IDP with SP by uploading certificates on either side.
Is signing certificate from SP mandatory to be configured in the IDP side ?
Best Regards,
Saurav

You only need a signing keypair on the SP side if you send the subject in the AuthnRequest, and your IdP utilizes the information when provided. If your SP isn't sending the subject attribute or your IdP won't consume it, you don't need it.

The defined SAML 2.0 specifications doesn't mandate that the request is signed.
4.1.3.3 <AuthnRequest> Is Issued by Service Provider to Identity Provider
...The <AuthnRequest> message MAY be signed, if authentication of the request issuer is required.
You can check with your Identity Provider documentation, but for example, Microsoft Azure AD does not validate signed requests, and there's no way to upload a request signing certificate.

Related

How to obtain the attributes of a saml response sent by Azure Active Directory?

I have a saml response that gives me azure active directory when doing the process with saml 2.0, the whole process is done normally, I send a saml request and the azure active directory returns the saml response, to do the whole process I have based on this guide, I've been reading a bit and I've noticed that Azure AD in the saml response sends the values within this tag:
<xenc:CipherData>
<xenc:CipherValue>VALUE HERE</xenc:CipherValue
</xenc:CipherData>
And not inside:
<AttributeStatement><Attribute Name="IDPEmail"><AttributeValue>administrator#contoso.com</AttributeValue></Attribute></AttributeStatement>
as specified in the documentation. The question is, how to get the true values that azure active directory is sent to me and not these encoded values, I am using Python 3 and Google App Engine, in addition to mentioning azure active directory and saml 2.0 to do the login process, I leave the SAML response complete in this url in case it serves to give a better context to my question.
As mentioned above, the SAML response you are getting is encrypted. Specifically Azure is encrypting its assertions (including the ones you are looking for) inside an encrypted body called CipherData.
You have two options:
1 - Disable SAML response encryption.
Azure AD calls SAML response encryption as SAML token encryption which is a bit confusing. You can follow this guide to disable the response. You must have uploaded an encryption public key/cert before.
2 - Configure your service provider to supported encrypted SAML responses.
The SAML token is encrypted.
You need to get the client side certificate used for this and use that to decrypt it.

What happens during a AcquireTokenAsync call using the client certificate?

In Azure AD, when we make a call such as AuthenticationContext.AcquireTokenAsync(resource, new ClientAssertionCertificate(_clientId, _cert)) it is not clear what exactly happens.
What part of the certificate gets exchanged if any?
Is there a challenge/response taking place?
Is the private key needed on the client as a part of this?
There are two ways you could go about finding the answer to you questions. One would be to look at the Microsoft Active Directory Authentication Library (ADAL) for .NET source code on GitHub, since this is open-source. The other (which we'll do here) is to looking at the network request that AcquireTokenAsync(String, ClientAssertion) generates, and work backwards from there.
Using Fiddler (or any other traffic analyzer), we can see something like the following (formatted for readability):
POST https://login.microsoftonline.com/{tenant-id}/oauth2/token HTTP/1.1
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials
&resource=https%3A%2F%2Fgraph.windows.net
&client_id={app-id}
&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer
&client_assertion=eyJhbGciOiJSUzI1N...VE8wHSf-HZvGQ
Breaking it down:
grant_type=client_credentials tells us this is a token request using the OAuth 2.0 Client Credentials Grant flow.
resource=https%3A%2F%2Fgraph.windows.net gives the URI of the resource the client is requesting an access token for. In this case, it's for the Azure AD Graph API.
client_id={app-id} is the client identifier. In Azure AD, this is the app ID of the application that was registered.
The presence of client_assertion_type and client_assertion are indicative that the client is using an assertion to authenticate:
client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer says that client assertion being used is a signed JSON Web Token (JWT).
client_assertion=eyJhbGciOiJSUzI1N...VE8wHSf-HZvGQ is the aforementioned signed JWT token. The authorization server (e.g. Azure AD) will validate the contents, and check that the token was indeed signed by the certificate authorized for the client in question.
So, what ADAL does is:
Construct a token with a set of claims about the client (your app)
Use your certificate's private key to generate a cryptographic signature of those claims
Bundle that up into a signed JWT
Make an appropriately formed token request to the authority
During AcquireTokenAsync, only the certificate's thumbprint is provided (it's included in the JWT header to help the authorization server look up the corresponding public key). The JWT's signature is what proves that the client is in possession of the private key. However, before AcquireTokenAsync(String, ClientAssertion) can be used successfully, the client owner (i.e. you) needs to have provided Azure AD with the certificate's public key.
There is no challenge/response taking place here. The token is obtained in a single request, initiated by the client.
For a lot more detail, you can review the standards that this all implements:
RFC 6749: The OAuth 2.0 Authorization Framework
RFC 7521: Assertion Framework for OAuth 2.0 Client Authentication and Authorization Grants
RFC 7523: JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants
RFC 7519: JSON Web Token (JWT)
(Note that ADAL has a cache. Everything I described above will take place only if ADAL does not find a valid access token in the token cache. You can use AuthenticationContext.TokenCache.Clear() to clear the cache for experimentation.)

Reusing SAML assertion

I am implementing single sign on with multiple SPs. Here is my basic understanding:
1) Browser(User) requests resource from Service Provider (SP).
2) SP Redirects (with SAML Request) to Identity Provider (IdP).
3) Since it is first login, User gives the (IdP) his/her valid credentials.
4) IdP then redirects Browser (with SAML Response which includes SAML token) to the SP page.
Now let's say I have Service Provider A and Service Provider B. A user has completed the step about for Service Provider A. From service provider A (salesforce.com in my scenario), I have written a server-side method which instantiates a callout to an endpoint on Service Provider B. Is it possible to re-use the SAML assertion in this case? I.e. will service provider B trust the backend method?
You would have to customize Service Provider B in order for it to accept, understand and interpret the Assertion obtained by Service Provider A. It would certainly not work out-of-the-box.
The SAML Assertion included in the SAML Response to Service Provider A contains pieces of data which correlate it with the original SAML Request and define recipients of the message (for example using elements SubjectConfirmationData and Audience). The Service Provider B would need to ignore values in these fields, as it is actually not the indented recipient of the Assertion.
The problem of how to broker trust between two machines where user's identity is asserted by an identity provider can be solved with multiple standard approaches. One is to use a Session Token Service (based on WS-Trust) which defines how to request and issue tokens to 3rd party services. Another is to use OAuth 2.0. You could of course also simply authenticate Service Provider A to Service Provider B using a custom scheme with a password, HMAC, ...
The short answer - no if Service Provider B is implemented as a standard SAML 2.0 SP.
SAML 2.0 assertions are "targeted" and signed. They have a specified audience and a recipient URL. You cannot change them without breaking the signature.
The assertion received by SP A contains the name of SP A as audience and the ACS end point of SP A as recipient URL. Such an assertion will not be accepted by SP B.
What prevents you from just calling SP B in a standard way and let it initiate its own SAML 2.0 flow? Another option would be to perform an IDP-initiated SSO flow for SP B. Not all IDP implementations support it though.

Why do I need to share the certificate with an SP for SSO when the certificate is included in the signed SAML response?

I am just wondering while implementing SAML SSO with Salesforce I realize that I uploaded the certificate to the SP side (i.e. Salesforce), however I can see when we send a signed SAML response it already includes the certificate.
Why is the certificate shared ahead of time with the SP?
It's all about establishing trust between systems. If you don't give SFDC your cert ahead of time, how can they trust the message you are sending is actually from your IDP? Without your cert ahead of time, they can validate that the message is intact but not who actually generated it. When you include your public key in the SAML Response, they can check that it's the same one you shared with them and it's the same one you used to generate the signature.

Signature Invalid/Configured Certificate Mismatch for SSO with SFDC

I did SSO of OpenAM and SalesForce.com (SFDC)
I have installed OpenAM-Client SDK to retrieve SAML Assertion from OpenAM.
I used this assertion data to generate SAML response required for SalesForce. When I pass this data to SFDC. I got error message for SAML.
“Failed: Signature Invalid/Configured Certificate Mismatch”
I used same certificate and signature data which I got from OpenAM-client SDK public API assertion.
At time of SSO configuration with SDFC. I used default certificate (test cert) provided by OpenAM.
Is there any way to retrieve test certificate and its signature from OpenAM ?
Run one of the failing SAML assertions through the SAML Validation tool inside Single Sign-On Settings in SFDC; you should get a slightly more useful error. The most likely cause of this is that you have not uploaded the correct certificate to SFDC as part of your SSO setup. Make sure the "Identity Provider Certificate" section of "Single Sign-On Settings" matches the cert contained in the assertion.

Resources