Forum Discussion

Doug_129661's avatar
Doug_129661
Icon for Nimbostratus rankNimbostratus
Sep 04, 2013

Manipulate SAML assertion data

I am new to F5 technology so I am not sure if this is areasonable question or not.

 

I wondered if it is possible to collect all the SAML data from the ID provider and then post that XML data to a web url. The data is more extensive than just info for sso and a downstream process needs all the attribute data.

 

Thanks

 

7 Replies

  • Can you please clarify this? Do you want to consume a SAML assertion from some IDP? Or do you want BIG-IP to act as an IDP? Or is your question regarding what BIG-IP can include into its SAML assertion when it acts as an IDP?
  • Sorry I wasn't clear. I want to consume an assertion from an external IDP. We are acting as the SP. I know what the data coming from the IDP will look like but rather than just validate it and use it for sso, I also need to send the data downstream to another process. Does that make sense?
  • Here's an idea followed by some additional questions. On successful validation as the SP, the assertion content is actually stored in a session variable. I don't have it in front of me, but it's something like "session.saml.assertion". This is the decoded XML. So then there are a lot of options for what to do with that. And now the questions:

     

    1. Do you need to send this assertion data as an actual (encoded) assertion, or maybe something simpler like an HTTP header?

       

    2. If the former, do you need it in a POST request as the first request to the site and using a specific (potentially different) entityID/app URL?

       

    3. If yes to 2, do you need to validate the internal SP's response?

       

  • I've had a chance to look at it, and the decoded assertion is stored in the session.saml.last.assertion session variable. So to go back to question 1, can this value be sent as an HTTP header (the easiest method), or is the application expecting an assertion POST?

    If the former, then something like this might work:

    when ACCESS_ACL_ALLOWED {
        if { [ACCESS::session data get session.saml.last.sent] == "" } {
            ACCESS::session data set session.saml.last.sent 1
            HTTP::header insert ASSERTION [b64encode [ACCESS::session data get session.saml.last.assertion]]
        }
    }
    

    This sends the base64-encoded assertion as an HTTP header ("ASSERTION") in the FIRST request to the server.

  • Hello all,

    coming back to this old but very interesting (to me) post. The I-rule proposed by Kevin works fine for me and i have been able to insert an HTTP HEADER with the assertion i am looking for thanks to :

    when ACCESS_ACL_ALLOWED {
     if { [ACCESS::session data get session.saml.last.sent] == "" } {
        ACCESS::session data set session.saml.last.sent 1
        HTTP::header insert MY_HTTP_HEADER_CITY [ACCESS::session data get session.saml.last.attr.name.city]
     }
    }
    

    However, and this is due to the fact that i admit all this is not crystal clear to me at all, i am wondering why this header is set only "in the FIRST request to the server" and also if i could have it set for each and every request.

    I guess this is due to ACCESS_ACL_ALLOWED event happening only once but...having said that and even after reading the documentation related to this event :

    ACCESS_ACL_ALLOWED – triggered right after HTTP_REQUEST (and before CACHE_REQUEST, not included in this drawing) for a request that has been allowed by ACLs. ACCESS checks the request for a valid session, valid policy result, and then evaluates ACLs. If ACL allows a request, it raises ACCESS_ACL_ALLOWED before releasing the request to the upper layers.
    

    this is still not clear to me. Any help would therefore be welcomed.

    Thanks a lot.

    With Regards

  • It's primarily because you're only sending the header if session.saml.last.sent is empty, and then immediately setting it to 1. Otherwise, ACCESS_ACL_ALLOWED does fire on every HTTP request.