Security Assertion Markup Language \(SAML\) is an open standard that allows identity providers \(IdP\) to pass authorization credentials to service providers \(SP\). What that jargon means is that you can **use one set of credentials to log into many different websites**. It’s much simpler to manage one login per user than it is to manage separate logins to email, customer relationship management \(CRM\) software, Active Directory, etc.
SAML transactions use Extensible Markup Language \(XML\) for standardized communications between the identity provider and service providers. SAML is the link between the authentication of a user’s identity and the authorization to use a service. \(From [here](https://www.varonis.com/blog/what-is-saml/)\)
### SAML vs. OAuth
OAuth is a slightly newer standard that was co-developed by Google and Twitter to enable streamlined internet logins. OAuth uses a similar methodology as SAML to share login information. **SAML provides more control** to enterprises to keep their SSO logins more secure, whereas **OAuth is better on mobile and uses JSON**.
1. Step 1 - We try to access some protected resource
2. Step 2 - The server where that resource resides \(Service Provider\) doesn’t know us, so it generates a **SAML Request** to be sent to the Identity Provider. This would be like showing up to Germany without our passport and getting sent back to the US to get our passport before being able to get into the country.
3. Step 3 - After generating the SAML Request, the SP **redirects** us to the IdP. Note: The SAML Request passes through our browser on the way to the IdP.
4. Step 4 - The IdP receives the SAML Request
5. Step 4a \(not pictured\) - The IdP provides some means of authentication; a login form or something similar.
6. Step 4b \(not pictured\) - The IdP validates us as a legitimate user that should be allowed to access the resource included as part of the SAML Request
7. Step 5 - The IdP creates a **SAML Response**. The SAML Response contains the SAML Assertions necessary for the SP. The Assertion usually includes the following information at a minimum: Indication that the Assertion is from the correct IdP, a **NameID** attribute specifying who the user is, and a digital signature. The SAML Response also passes through our browser.
8. Step 6 - The IdP **redirects** us to the SP’s Assertion Consumer Service \(ACS\) URL. The ACS is simply the URL on which the SP expects to receive SAML assertions.
9. Step 7 - The ACS validates the SAML Response.
10. Step 8 - We are allowed to access the resource we originally requested.
### SAML Request Example <a id="saml-request-example"></a>
Let’s take a closer look at steps 2 and 3 outlined above. We’ll make a request to the example Service Provider for the resource located at [https://shibdemo-sp1.test.edu/secure/](https://shibdemo-sp1.test.edu/secure/), which as its name implies, is content that requires us to be authenticated to view.
_shibdemo-sp1.test.edu is a local virtualized instance of an IdP and SP for testing, not an actual site_
```text
GET /secure/ HTTP/1.1
Host: shibdemo-sp1.test.edu
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:65.0) Gecko/20100101 Firefox/65.0
* **AssertionConsumerServiceURL**: Identifies where the IdP should send the SAML Response to after authentication
* **Destination**: Indicates the address to which the request should be sent \(IdP\)
* **ProtocolBinding**: Typically accompanies the AssertionConsumerServiceURL attribute; defines the mechanism by which SAML protocol messages will be transmitted
* **saml:Issuer**: Identifies the entity that generated the request message
We’ve outlined the more pertinent elements of the request above, but details about any of the other elements can be viewed in the [core specification](https://docs.oasis-open.org/security/saml/v2.0/saml-core-2.0-os.pdf). The request above goes something like this: “Hey, please authenticate the user that sent this message to you and then have that same user hit me up when you two are done”.
With the SAML Request created, the SP now replies to our GET request for `/secure/` with a **302 redirect**. The 302 directs our browser to head over to the IdP. The SAML Request is encoded into the HTTP response’s **Location** header as part of the 302.
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>302 Found</title>
</head><body>
<h1>Found</h1>
<p>The document has moved <ahref="https://shibdemo-idp.test.edu/idp/profile/SAML2/Redirect/SSO?SAMLRequest=fZJdT4MwFIb%2FCuk9FNgmWzNIcLtwyXRkoBfemFKO0gRa7Cl%2B%2FHvZmDoTs8u2b5%2B350mXyNumY2lva7WH1x7QOh9to5AdD2LSG8U0R4lM8RaQWcHy9HbLQs9nndFWC90QJ0UEY6VWK62wb8HkYN6kgPv9Nia1tR0ySrGWZQWtdrELPDs0eVD1NB92S92ArT1ETQ%2FwkGa7vCDOeshIxQ%2Fcfyiy6n4pw4IOz3mWDZwQe6ikAWFpnu%2BIs1nH5ElUHKJgHk7mJV%2BI0I%2F4ZCZEJCK%2F9KdX3B9iiD1sFFqubExCP1i4%2FsQNwiL02WzKZvNH4mSnqa%2BlqqR6uayoHEPIbooic8exHsDgcaQhQJLlQTQ7Fpsz9Zex%2FNs3SS7bxR%2B7S3pWNLZ27G4gb9aZbqT4dNKm0e8rA9xCTAJCk%2FHK39%2BRfAE%3D&RelayState=ss%3Amem%3A39430bdac29d44586c326f12b4cb3345ffa47137a374e37cba0877e0fc79ea91">here</a>.</p>
<hr>
<address>Apache/2.2.3 (CentOS) Server at shibdemo-sp1.test.edu Port 443</address>
</body></html>
```
The **RelayState** parameter sent along with the SAML Request is state information sent by the SP to the IdP so that the SP knows who initially asked for the resource when the SAML Response comes back. The SAML Response must contain the same RelayState value.
The **SAMLRequest** parameter is a **compressed** and **encoded** version of the same raw xml snippet we looked at earlier. SAML uses the [Deflate compression](https://en.wikipedia.org/wiki/DEFLATE) algorithm then base64 encodes the result.
### SAML Response Example <a id="saml-response-example"></a>
We’re going to eschew stepping through the part where the user authenticates to the IdP and jump straight into steps 5 and 6 from what was discussed in the [SAML Authentication Workflow](https://epi052.gitlab.io/notes-to-self/blog/2019-03-07-how-to-test-saml-a-methodology/#saml-authentication-workflow). Just keep in mind that what we’re going to look at happens **after** the user authenticates to the IdP.
Let’s start by taking a look at the raw SAML Response.
* **ds:Signature**: An [XML Signature](https://www.w3.org/TR/xmldsig-core1/#sec-KeyInfo) that protects the integrity of and authenticates the issuer of the assertion; the SAML assertion MAY be signed but doesn’t have to be. The example above contains two ds:Signature elements. The reason is that one is the message’s signature; the other is the Assertion’s signature.
* **saml:Assertion**: Contains information about the user’s identity and potentially other user attributes.
* **saml:Subject**: Specifies the principal that is the subject of all of the statements in the assertion.
* **saml:StatusCode**: A code representing the status of the activity carried out in response to the corresponding request.
* **saml:Conditions**: Specifies things like the time an Assertion is valid and that the Assertion is addressed to a particular Service Provider.
* **saml:AuthnStatement**: States that the IdP authenticated the Subject of the Assertion.
* **saml:AttributeStatement**: Contains Attributes that describe the Subject of the Assertion.
Here’s a more straightforward visual representation of the same SAML Response.
The 302 ultimately leads to us making a POST request to the Service Provider’s Assertion Consumer Service URL. The POST body contains the RelayState and SAMLResponse parameters. Recall that the ACS processes and validates the SAML Response.
```markup
POST /Shibboleth.sso/SAML2/POST HTTP/1.1
Host: shibdemo-sp1.test.edu
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:65.0) Gecko/20100101 Firefox/65.0
The request number 5 from the previous image sends back the information from the identity provider to the service provider. This information is **usually signed** at the end of the message so **no tampering with the information is possible**. It's recommended to check what happens in case the information is sent **stripping the signature** from the message.