Forum Discussion

seamlessfirework's avatar
Aug 22, 2023

APM / responding session ID to client with JSON

He guys

I am protecting several APIs with the APM module. In case of an error responds are sent in JSON with a plain and simple message "401 unauthorized" with an iRule and a custom iRule event in the VPE.

I tried to get the session id like this

when CLIENT_ACCEPTED {
    # sonst wird der HTTP_RESPONSE_RELEASE Event nicht ausgeloest
    ACCESS::restrict_irule_events disable
    if { [ACCESS::session exists] } {
    set userSessionId [ACCESS::session sid]
    }
}

when ACCESS_PER_REQUEST_AGENT_EVENT {
    log local0. "[ACCESS::perflow get perflow.irule_agent_id]"

    if { [ACCESS::perflow get perflow.irule_agent_id] eq "Return401" } {
        ACCESS::session data set session.custom.Return401 "1"
    }
}

when HTTP_RESPONSE_RELEASE {
    set block [ACCESS::session data get session.custom.Return401]
    if { $block eq "1" } {
        HTTP::respond 401 content "{\"title\":\"Unauthorized\",\"status\":401\"sessionid":$userSessionId}" noserver Connection Close WWW-Authenticate Bearer
        ACCESS::session remove
    }
}

With this configuration I cannot connect to the service at all. Is it even possible to sent the session id with the response to the client? And if yes do you have any hints for me how to do this?

2 Replies

  • Instead of checking the client ID in CLIENT_ACCEPTED, use the other events eg ACCESS_SESSION_STARTED 

    Access events 

    The first thing to do is logging - log the session ID as a starting point, log the PRP agent, log the original http response etc. Maybe use HTTP::respond in that event rather than HTTP_RESPONSE

  • Hey PeteWhite,

    Thanks for your reply and sorry for my delayed reply. In the meantime I had a discussion with one of my go-to F5 engineers who found a solution for me. Here we go:

    when HTTP_RESPONSE_RELEASE {
        set block [ACCESS::session data get session.custom.Return401]
        # set variable to Return401
        log local0. "Block: $block"
        if { $block eq "1" } {
        # respond JSON when variable block equals 1
            set userSessionId [string range [ACCESS::session sid] end-7 end]
            HTTP::respond 401 content "{\"title\":\"Unauthorized\",\"status\":401,\"sessionid\":\"$userSessionId\"}" noserver Connection Close WWW-Authenticate Bearer
            # respond 401 with JSON body and include "WWW-Authenticate Bearer" in header
            # include last 8 bits of MRH session id
            ACCESS::session remove
        }
    }