F5 Sites
  • F5.com
  • F5 Labs
  • MyF5
  • NGINX
  • Partner Central
  • Education Services Portal (ESP)
Contact
  • Under Attack?
  • F5 Support
  • DevCentral Support
  • F5 Sales
  • NGINX Sales
  • F5 Professional Services
Skip to contentBrand Logo
Forums
CrowdSRC
Articles
GroupsEventsSuggestionsHow Do I...?
RegisterSign In
  1. DevCentral
  2. CrowdSRC
  3. CodeShare

APM Sharepoint authentication

Problem this snippet solves: Updated version to support Webdav with windows explorer after Nicolas's comment. APM is a great authentication service but it does it only with forms. The default be...
Published Apr 20, 2016
Version 1.0
BIG-IP Access Policy Manager (APM)
editing office documents
iRules
ms-ofba
programmability contest
security
sharepoint
Stanislas_Piro2's avatar
Stanislas_Piro2
Icon for Cumulonimbus rankCumulonimbus
Joined January 04, 2011
View Profile
Kai_Wilke's avatar
Kai_Wilke
Icon for MVP rankMVP
Sep 12, 2016

Hi Stanislas,

In a native ADFS-based SharePoint collaboration scenario you cannot use AD fallbacks. The SAML user accounts are most likely stored in many decentralized repositories, without a direct trust nor network access to them.

My goal was to get everything working without using the AD fallback at all. Well, I had to skip the support for outdated MS Office products and changed the handling of Microsoft WebDav Clients slightly. In addition I've restructured the code here and there to reduce the complexity and increase the performance...

when CLIENT_ACCEPTED {
    set inject_session_cookie 0
}
when HTTP_REQUEST {
     Check if APM session cookie is present and valid
    if { ( [set sessionid [HTTP::cookie value "MRHSession"]] ne "" ) and
         ( [ACCESS::session exists -state_allow $sessionid] ) } then {
         Allow the successfully pre authenticated request to pass
    } else {
         Check if persistent APM session cookie is present and valid
        if { ( [set sessionid [HTTP::cookie value "MRHSession_SP"]] ne "" ) and
         ( [ACCESS::session exists -state_allow $sessionid] ) } then {
             Restore APM session cookie value
            HTTP::cookie insert name "MRHSession" value $sessionid
            set inject_session_cookie 1 
             Allow the successfully pre authenticated request to pass
        } else {
             Enumerate explicit MS-OFBA authentication capabilities
             Background: https://msdn.microsoft.com/en-us/library/office/cc313069(v=office.12).aspx
            if { ( [HTTP::header "X-FORMS_BASED_AUTH_ACCEPTED"] equals "t" ) or 
                 ( [HTTP::header "X-FORMS_BASED_AUTH_ACCEPTED"] equals "f" ) } then {
                 Explicit MSOFBA support detected. 
                set authschema "ms-ofba"
            } else {
                 Enumerate implicit MS-OFBA authentication capabilities
                switch -glob -- [string tolower [HTTP::header "User-Agent"]] "*office protocol discovery*" - \
                  "*microsoft office*" - \
                  "*microsoft data access internet publishing provider*" - \
                  "*non-browser*" - \
                  "msoffice 12*" - \
                  "*microsoft-webdav-miniredir*" - \
                  {*ms frontpage 1[23456789]*} {
                     Implicit MSOFBA support detected.   
                    set authschema "ms-ofba"
                } "*ms frontpage*" {
                     Legacy client detected
                    set authschema "legacy"
                } "*mozilla*" - \
                  "*opera*" {
                     Regular web browser detected.  
                    set authschema "browser"
                } default { 
                    set authschema "legacy"
                }
            }
            if { $authschema eq "ms-ofba" } then {
                 Send a MSOFBA compatible Access Denied response 
                if { [HTTP::path] ne "/sp-msofba-form" } then {
                    HTTP::respond 403 -version "1.1" \
                                      content "Access Denied. Make sure that your client is correctly configured. See https://support.microsoft.com/en-us/kb/932118 for further information." \
                                      noserver \
                                      "Content-Type" "text/html" \
                                      "X-FORMS_BASED_AUTH_REQUIRED" "https://[getfield [HTTP::host] ":" 1]/sp-msofba-form" \
                                      "X-FORMS_BASED_AUTH_RETURN_URL" "https://[getfield [HTTP::host] ":" 1]/sp-msofba-completed" \
                                      "X-FORMS_BASED_AUTH_DIALOG_SIZE" "800x600" \
                                      "Set-Cookie" "MRHSession=deleted;path=/;secure" \
                                      "Set-Cookie" "LastMRH_Session=deleted;path=/;secure" \
                                      "Set-Cookie" "MRHSession=deleted; expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/;secure" \
                                      "Set-Cookie" "LastMRH_Session=deleted; expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/;secure"
                }
            } elseif { $authschema eq "legacy" } then {
                 Send a regular Access Denied response 
                HTTP::respond 403 content "Access denied. An unsupported client access has been detected."
            } else {
                 Let the regular web browser request pass to the APM policy
            }
        }
    }
}

when ACCESS_SESSION_STARTED {
    if { [HTTP::cookie value "SAML_Realm"] ne "" } then {
        ACCESS::session data set "session.irule.realmcookie" [HTTP::cookie value "SAML_Realm"]
    }
}
when ACCESS_POLICY_COMPLETED {
    if { [set realm_cookie [ACCESS::session data get "session.irule.setrealmcookie"]] ne "" } then {
        ACCESS::respond 302 "Location" "[ACCESS::session data get "session.server.landinguri"]" "Set-Cookie" "SAML_Realm=$realm_cookie;path=/;secure"
    } else {
        ACCESS::respond 302 "Location" "[ACCESS::session data get "session.server.landinguri"]" 
    }
}
when ACCESS_ACL_ALLOWED {
    switch -glob -- [string tolower [HTTP::path]] "/sp-msofba-form" {
         Successfully APM authenticated request MS-OFBA request detected. Redirect to MS-OFBA return URL
        ACCESS::respond 302 noserver Location "/sp-msofba-completed"
    } "/sp-msofba-completed" {
         Successfully APM authenticated request MS-OFBA request detected. Sending MS-OFBA return response
        ACCESS::respond 200 content "AuthenticatedGood Work, you are Authenticated" noserver
    } "*/signout.aspx" {
         SharePoint SignOut signature detected. Disconnect session and redirect to APM logout Page
        ACCESS::respond 302 noserver Location "/vdesk/hangup.php3"
    } "/_layouts/accessdenied.aspx" {
         SharePoint AccessDenied signature detected.
        if { [string tolower [URI::query [HTTP::uri] loginasanotheruser]] equals "true" } then {
             SharePoint LoginAsAnotherUser request detected. Killing the APM session an sending redirect to www-root.
            ACCESS::session remove
            ACCESS::respond 302 noserver Location "/"
            return
        }
    } default {
          Let the authenticated request pass
    }
}
when HTTP_RESPONSE {
    if { [HTTP::header "Content-Type" ] contains "text/html" } then {
         Insert persistent APM session cookie into HTTP response.
        HTTP::header insert "Set-Cookie" "MRHSession_SP=$sessionid;path=/;secure"
        HTTP::cookie expires "MRHSession_SP" 120 relative
    }
    if { $inject_session_cookie } then {
         Insert APM session cookie into HTTP response.
        HTTP::header insert "Set-Cookie" "MRHSession=$sessionid;path=/;secure"
        set inject_session_cookie 0
    }
}

Note: Your Clientless_Mode support can be easily included in the provided script. You just need to insert your existing code into the

elseif { $authschema eq "legacy" } then {
script block and add the other iRule events. But be aware that the query to
[ACCESS::user getsid $user_key]
exposes some security risks, since it can be used to bypass active account lockouts.

Update: Changed the session cookie injection mechanism.

Cheers, Kai

Help guide the future of your DevCentral Community!

What tools do you use to collaborate? (1min - anonymous)

ABOUT DEVCENTRAL

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

RESOURCES

Product DocumentationWhite PapersGlossaryCustomer StoriesWebinarsFree Online CoursesTraining & Certification

SUPPORT

Manage SubscriptionsProfessional ServicesCreate a Service RequestSoftware DownloadsSupport Portal

PARTNERS

Find a Reseller PartnerTechnology AlliancesBecome an F5 PartnerLogin to Partner Central

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