F5 Sites
  • F5.com
  • LearnF5
  • NGINX
  • MyF5
  • Partner Central
Contact
  • Under Attack?
  • F5 Support
  • DevCentral Support
  • F5 Sales
  • NGINX Sales
  • F5 Professional Services
Skip to contentBrand Logo
Forums
CrowdSRC
Articles
Groups
EventsSuggestionsHow Do I...?
RegisterSign In
  1. DevCentral
  2. CrowdSRC
  3. CodeShare

Digest based Single-Sign-On

Problem this snippet solves: Sometimes, you are asked to implement some unusual Single Sign On methods. This code helps to deal with Digest based SSO when configured. This specific implementation su...
Updated Jun 06, 2023
Version 2.0
application delivery
BIG-IP Access Policy Manager (APM)
devops
iRules
security
Yann_Desmarest's avatar
Yann_Desmarest
Icon for Cirrus rankCirrus
Joined September 11, 2012
View Profile
Chun_Kit_Cheng's avatar
Chun_Kit_Cheng
Ret. Employee
Jul 27, 2018

1/ The server nonce value might contain equal sign so the above code will chop it off in an unintended way.

 

2/ It would need a condition block in HTTP_REQUEST to identify if it is a request from HTTP::retry.

 

when RULE_INIT {
    set static::user "testuser"
    set static::password "testpass"
    set static::client_nonce "389db6597243daf2"
    set static::nonce_count "00000001"
}
when CLIENT_ACCEPTED {
    set retried 0
}
when HTTP_REQUEST {
    if { ${retried} == 0 } {
         set vars required for Digest SSO
        set uri [HTTP::uri]
        set method [HTTP::method]
        set retried 0

         insert a dummy text. Help to inject Digest SSO
        HTTP::header replace Authorization "irule-test-digest-sso"
        set request [HTTP::request]
        HTTP::header remove Authorization
    }
}
when HTTP_RESPONSE {
    if { [HTTP::status] contains "401" and [HTTP::header exists "WWW-Authenticate"] and [HTTP::header "WWW-Authenticate"] contains "Digest" and $retried == 0 } {
        set www_auth [HTTP::header "WWW-Authenticate"]
         basically chop the "realm=" and "nonce=" using strictly string functions
        set realm [string range ${www_auth} [expr {[string first "realm=" ${www_auth}] + 7}] [expr {[string first "," ${www_auth} [string first "realm=" ${www_auth}]] - 2}]]
        set nonce [string range ${www_auth} [expr {[string first "nonce=" ${www_auth}] + 7}] [expr {[string first "," ${www_auth} [string first "nonce=" ${www_auth}]] - 2}]]

         retrieve username and password from wherever you want. Can be APM, Basic authentication, ...
        binary scan [md5 "$static::user:$realm:$static::password"] H* ha1
        binary scan [md5 "$method:$uri"] H* ha2
        binary scan [md5 "$ha1:$nonce:$static::nonce_count:$static::client_nonce:auth:$ha2"] H* response

        set retried 1
        set auth_value "Digest username=\"$static::user\", realm=\"$realm\", nonce=\"$nonce\", uri=\"$uri\", algorithm=MD5, response=\"$response\", qop=auth, nc=$static::nonce_count, cnonce=\"$static::client_nonce\""

         insert Authorization header with Digest
        set updated_request [string map [list "irule-test-digest-sso" "$auth_value"] $request] 

         resend the request with the Authorization header filled
        HTTP::retry $updated_request
    } else {
        set retried 0
    }
}

Hopefully this would help someone working on this trick.

 

ABOUT DEVCENTRAL

DevCentral NewsTechnical ForumTechnical ArticlesTechnical CrowdSRCCommunity GuidelinesDevCentral EULAGet a Developer Lab LicenseBecome a DevCentral MVP

RESOURCES

Product DocumentationWhite PapersGlossaryCustomer StoriesWebinarsFree Online CoursesF5 CertificationLearnF5 Training

SUPPORT

Manage SubscriptionsProfessional ServicesProfessional ServicesCreate a Service RequestSoftware DownloadsSupport Portal

PARTNERS

Find a Reseller PartnerTechnology AlliancesBecome an F5 PartnerLogin to Partner Central

F5 logo©2024 F5, Inc. All rights reserved.
TrademarksPoliciesPrivacyCalifornia PrivacyDo Not Sell My Personal Information