For more information regarding the security incident at F5, the actions we are taking to address it, and our ongoing efforts to protect our customers, click here.

Forum Discussion

NetSnoopy's avatar
NetSnoopy
Icon for Cirrus rankCirrus
Apr 11, 2017

Saml token convert to jwt

Hello,

I create a iRule for convert saml token to JWT (json web token). It works well but I get a signatur error. I try many option and formats. But nothing works. I'm shure you can help me easily.

I have creat a working access Profile with saml. Bigip is SP and an external IdP. Here my iRule.

when ACCESS_ACL_ALLOWED {
        set hamacsha256 secret
       set secret_key "secret"

        get data from saml Session (APM->Manage Sessions-> Variables -> View)
       set user [ACCESS::session data get session.saml.last.nameIDValue]
       set sub [ACCESS::session data get session.saml.last.attr.name./EmployeeID]
       set nbf [ACCESS::session data get session.saml.last.validityNotBefore]
       set exp [ACCESS::session data get session.saml.last.validityNotOnOrAfter]
       set email [ACCESS::session data get session.saml.last.attr.name./identity/claims/emailaddress]
       set surname [ACCESS::session data get session.saml./Common/xyz_auth_ag.attr.name./identity/claims/surname]
       set givenname [ACCESS::session data get session.saml./Common/xyz_auth_ag.attr.name./identity/claims/givenname]
       set aud [ACCESS::session data get session.saml.last.assertionIssuer]
       set gpid [ACCESS::session data get session.saml.last.attr.name./GPID]

        Name of the cookie
       set cookie_name "xyz-JWT"

        set cookie header
       set cookie_header "[b64encode "{\r\n \"alg\": \"HS256\", \r\n \"typ\": \"JWT\"\r\n}"]"

        set cookie payload
       set cookie_payload "[b64encode "{\r\n \"user\": \"$user\",\r\n \"sub\": \"$sub\",\r\n \"nbf\": \"$nbf\",\r\n \"exp\": \"$exp\",\r\n \"email\": \"$email\",\r\n \"surname\": \"$surname\",\r\n \"givenname\": \"$givenname\",\r\n \"aud\": \"$aud\",\r\n \"gpid\": \"$gpid\"\r\n}"]"

       set cookie data for signatur
       set cookie_data [concat "[b64encode [URI::encode $cookie_header]].[b64encode [URI::encode $cookie_payload]]"]
        test some other version
       set cookie_data "[URI::encode [b64encode $cookie_header]]\".\"[URI::encode [b64encode $cookie_payload]]"
       set cookie_data "[URI::encode $cookie_header]\".\"[URI::encode $cookie_payload]]"
       set cookie_data $cookie_header"."$cookie_payload
       log local0. "cookie_data $cookie_data"

       create signatur
       set cookie_sig "[CRYPTO::sign -alg hmac-sha256 -key $secret_key $cookie_data]"
       convert signatur in some version
       set cookie_sig_b64 "[b64encode $cookie_sig]"
       set cookie_sig_b64_url "[URI::encode $cookie_sig_b64]"
       set cookie_sig_url_b64 "[b64encode $cookie_sig_url]"
       log local0. "sig_b64= $cookie_sig_b64"
       log local0. "sig_b64_url= $cookie_sig_b64_url"
       log local0. "sig_url_b64= $cookie_sig_url_b64" 

       verify signatur
       if { [CRYPTO::verify -alg hmac-sha256 -key $secret_key -signature $cookie_sig $cookie_data] } {
           log local0. "Data verified"
       }

       create full JWT
       set cookie "$cookie_header.$cookie_payload.$cookie_sig_url_b64"
       HTTP::cookie insert name $cookie_name value $cookie
       log local0. "$cookie_name $cookie"
    }

    send to client
    when HTTP_RESPONSE {
        HTTP::cookie insert name $cookie_name value $cookie
        }

If I verify the cookie with jwt.io (webseite). I get alway a signatur error. All other works. The json notation for signatur is

HMACSHA256(
      base64UrlEncode(header) + "." +
      base64UrlEncode(payload),
      secret
    ) secret base64 encoded

I think I have a mistake in format for cookie_data. In the version you can see some of my tests. How can help me?

Cheers, NetSnoopy

2 Replies

  • Hello,

    i found my mistake and now it's working. Here is the working iRule

    when ACCESS_ACL_ALLOWED {
         set hamacsha256 secret
        set secret_key "secret"
         get date from Saml Session
        set user [ACCESS::session data get session.saml.last.nameIDValue]
        set sub [ACCESS::session data get session.saml.last.attr.name.http://xxxx.de/EmployeeID]
        set nbf [ACCESS::session data get session.saml.last.validityNotBefore]
        set exp [ACCESS::session data get session.saml.last.validityNotOnOrAfter]
        set email [ACCESS::session data get session.saml.last.attr.name.http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress]
        set surname [ACCESS::session data get session.saml./Common/kosmos-uat_APM_Test_act_saml_auth_ag.attr.name.http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname]
        set givenname [ACCESS::session data get session.saml./Common/kosmos-uat_APM_Test_act_saml_auth_ag.attr.name.http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname]
        set aud [ACCESS::session data get session.saml.last.assertionIssuer]
        set gpid [ACCESS::session data get session.saml.last.attr.name.http://xxxx.de/xxxx-User-GPID]
        generate JWT
        set jwt_header "[b64encode "{\r\n \"alg\": \"HS256\", \r\n \"typ\": \"JWT\"\r\n}"]"
        set jwt_payload "[b64encode "{\r\n \"user\": \"$user\",\r\n \"sub\": \"$sub\",\r\n \"nbf\": \"$nbf\",\r\n \"exp\": \"$exp\",\r\n \"email\": \"$email\",\r\n \"surname\": \"$surname\",\r\n \"givenname\": \"$givenname\",\r\n \"aud\": \"$aud\",\r\n \"gpid\": \"$gpid\"\r\n}"]"
        set jwt_data "$jwt_header.$jwt_payload"
        set jwt_sig "[b64encode [CRYPTO::sign -alg hmac-sha256 -key $secret_key $jwt_data]]"
        set jwt "$jwt_header.$jwt_payload.$jwt_sig"
        log local0. "JWT $jwt"
    }
    
    when HTTP_REQUEST {
        if { [info exists jwt] }{
        HTTP::header insert Authorization "Bearer $jwt"
        }
    }
    

    In this case the JWT will only send to Server but not to Client. If you want this also to Client and the follow lines

    when HTTP_RESPONSE {
        if { [info exists jwt] }{
        HTTP::header insert Authorization "Bearer $jwt"
        }
    }
    

    I hope I can help someone with this example.

    Cheers, NetSnoopy

  • Cri's avatar
    Cri
    Icon for Nimbostratus rankNimbostratus

    Sounds good NetSnoopy!

     

    thank you very much! Only one question: you are using "nbf" as timestamp but I saw that in the JWT spec they suggest to use "iat", any reason?

     

    Cheers Pomello

     

    UPDATE: Sorry, I found the difference between iat and nbf ;)

     

    Thank you