11

I've been tasked with designing a very simple SSO (single sign-on) process. My employer has specified that it should be implemented in SAML. I'd like to create messages that are absolutely as simple as possible while confirming to the SAML spec.

I'd be really grateful if some of you would look at my request and response messages and tell me if they make sense for my purpose, if they include anything that doesn't need to be there, and if they are missing anything that does need to be there.

Additionally, I'd like to know where in the response I should put additional information about the subject; in particular, the subject's email address.

The interaction needs to work as follows:

  1. User requests service from service provider at this point, the service provider knows nothing about the user.
  2. Service provider requests authentication for user from identity provider
  3. User is authenticated/registered by identity provider
  4. Identity provider responds to Service provider with authentication success message, PLUS user's email address.

Here's what I think the request should be:

<?xml version="1.0" encoding="UTF-8"?>
<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" 
ID="abc" 
IssueInstant="1970-01-01T00:00:00.000Z" 
Version="2.0"
AssertionConsumerServiceURL="http://www.IdentityProvider.com/loginPage">
   <saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
    http://www.serviceprovider.com
    </saml:Issuer>
    <saml:Subject>
        <saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient">3f7b3dcf-1674-4ecd-92c8-1544f346baf8</saml:NameID>
    </saml:Subject>

Here's what I think the response should be:

<?xml version="1.0" encoding="UTF-8"?>
<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Destination="http://www.serviceprovider.com/desitnationURL" ID="123" IssueInstant="2008-11-21T17:13:42.872Z" Version="2.0">
    <samlp:Status>
        <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
    </samlp:Status>
    <saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" Version="2.0">
        <saml:Subject>
            <saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient">3f7b3dcf-1674-4ecd-92c8-1544f346baf8</saml:NameID>
            <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:profiles:SSO:browser">
                <saml:SubjectConfirmationData InResponseTo="abc"/>
            </saml:SubjectConfirmation>
        </saml:Subject>
        <saml:AuthnStatement AuthnInstant="2008-11-21T17:13:42.899Z">
            <saml:AuthnContext>
                <saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml:AuthnContextClassRef>
            </saml:AuthnContext>
        </saml:AuthnStatement>
    </saml:Assertion>
</samlp:Response>

So, again, my questions are:

  1. Is this a valid SAML interaction?

  2. Can either the request or response XML be simplified?

  3. Where in the response should I put the subject's email address?

I really appreciate your help. Thanks so much!

-Morgan

morgancodes
  • 25,055
  • 38
  • 135
  • 187

2 Answers2

12

You don't need a Subject in the request - looking at the specs, I think it can be this simple:

<?xml version="1.0" encoding="UTF-8"?>
<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
  ID="abc" Version="2.0" IssueInstant="1970-01-01T00:00:00.000Z"
</samlp:AuthnRequest>

Omitting all the optional elements and attributes (Issuer, NameIDPolicy, AssertionConsumerServiceURL etc) means that your identity provider and service provider have agreed these up front, so they don't need to be specified in the AuthnRequest. If you're in control of both ends and you absolutely know that you'll never add another provider to the mix then this is a perfectly legal SAML request. It means "Authenticate the user who presents this via the mechanism we agreed".

Looking at the response, I think this is the minimal case:

<?xml version="1.0" encoding="UTF-8"?>
<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
  ID="123" InResponseTo="abc" IssueInstant="2008-11-21T17:13:42.872Z" 
  Version="2.0">
    <samlp:Status>
        <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
    </samlp:Status>
    <saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" Version="2.0">
        <saml:Subject>
            <saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">
                user@example.com
            </saml:NameID>
        </saml:Subject>
        <saml:AuthnStatement AuthnInstant="2008-11-21T17:13:42.899Z">
            <saml:AuthnContext>
                <saml:AuthnContextClassRef>
                    urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport
                </saml:AuthnContextClassRef>
            </saml:AuthnContext>
        </saml:AuthnStatement>
    </saml:Assertion>
</samlp:Response>

You can send the user's email address as the NameID, and the AuthnStatement just carries the fact that the identity provider authenticated the user at the given time by the given mechanism. Again, this is stripped to the bone - we omit attributes and elements such as Destination and SubjectConfirmationMethod as they are superfluous to the use case.

So, this response says "This is user@example.com; he logged in with a password over a protected transport (SSL/TLS) at 17:13:42 on 11/21/2008".

You should take a look at the SAML 2.0 profiles spec for the exact mechanism for passing these back and forth. The AuthnRequest is usually compressed, encoded and passed as a URL parameter in a GET, while the simplest way to return the Response is via the POST binding - return an HTML page with a form whose target is the service provider, and which is submitted at page load time via some JavaScript.

metadaddy
  • 4,234
  • 1
  • 22
  • 46
  • : What is the use of issue instant in request message. Is it used anywhere in IdProvider? – suraj Apr 12 '12 at 05:18
  • 1
    @metadaddy : why is there a issue instant and an auth instant in the respnse. You said that the auth instant is the time at which the user was authenticated by the IDP. And one more doubt I have is that shouldn't the ID in response have a tag before it. – Ashwin Apr 12 '12 at 05:20
  • @suraj, IssueInstant tells the identity provider when the request was created. The identity provider could use this to implement some policy - e.g. reject requests received more than 5 minutes after they were created. – metadaddy Apr 12 '12 at 22:29
  • @Ashwin, IssueInstant is when the SAML response was created; AuthnInstant is when the user authenticated - this could be some time before IssueInstant. You are correct on InResponseTo - it's optional in the SAML spec, but you have to provide it if the message is in response to a request - I'll edit my answer to be correct - thanks! – metadaddy Apr 12 '12 at 22:33
  • @metadaddy : you are welcome! Why does SAML spec specify AuthInstant as well as Issueinstant? Isn't any one enough? – Ashwin Apr 13 '12 at 02:09
  • @Ashwin, I might log in to a system at the identity provider at 9am, and be given a 2 hour session. At 10am I visit a service provider. I already have a session at the identity provider, so it just issues a response without asking me to re-authenticate. That response will give 9am as AuthnInstant and 10am as IssueInstant. It's up to the service provider what it does with this information. – metadaddy Apr 13 '12 at 15:05
  • @metadaddy I am new to saml2. AuthRequest doesn't specify which user we are authenticating. How does Idp returns the NameID - user@example.com in response? – Sanjeev Kumar Dangi Dec 24 '12 at 07:10
  • @SanjeevKumarDangi AuthRequest requests that the IdP authenticate the user. Typically the IdP does this by prompting the user for credentials (e.g. username/password). Thus the IdP knows who the user is and returns the NameID in the response. – metadaddy Dec 24 '12 at 16:23
  • @metadaddy thanks. But I have another use case. I am not able to interpret how single sign on works. Suppose there are tow SPs- A and B and one Idp -I. User sends auth request from A and is authenticated and receives a ticket from IdP. Now, user click on a link and moves to B. How does B knows which user is this? Does http request for outgoing link of B sends the ticket in Request Header and on server side, the applications requests assertion with this ticket and IdP says that this ticket is live and server can also fetch attributes like username associated with this ticket. Please explain – Sanjeev Kumar Dangi Dec 26 '12 at 19:16
1
  1. Yes, it seems to be a SAML interaction

  2. Your authentication response is rather simple now. Usually you would want to add more attributes in your assertions. And for the security sake, at least the response should be signed.

  3. It uses to be set after the .In your case you do not have it, so after the status should be ok...

I would recommend you to create an account in http://www.ssocircle.com, and with one HTTP headers profiler (i.e. the classic and great LiveHttpHeaders) and a SAML2 debugger (Feide Rn SAML2 debugger thanks guys!) take a look at the request/response flow...

Hope it helps,

Luis

ps: if you want to take a look at a complete implementation SP/IdP: http://sourceforge.net/projects/spring-saml/files%2F0.1/

Gaucho
  • 899
  • 1
  • 12
  • 25