Forum Discussion
Steven_Ruby_872
Nimbostratus
Jan 17, 2006more fun with jsessionid persistence
so it seems that some people in development, have decided that we shouldnt make cookies a requirement in our webapp. That means if a clients browser doesnt allow cookies the COOKIE persistence wont work.
What is the best way to use both the COOKIE persistence and if there is no cookie then use UIE persistence based on the jsessionid in the uri?
Anyone have ideas?
sr
8 Replies
- Steven_Ruby_872
Nimbostratus
I get the general idea. My problem is it doesnt work.
in the middle of a session it will flip to another server, which means the user has to authenticate again. i also dont see a persistence table entry ever created.
sr - JRahm
Admin
Is anyone successfully doing this? From a tcpdump, here is what I am interpreting:
1) Client sends initial request
2) Server responds with JSESSIONID= cookie AND links with JSESSIONID= built in to URI
3) BIGIP evaluates
a) If cookie present, add persistence.
b) If no cookie present, lookup jsessionid in URI and add persistence
THe problem with both A & B is the persistence will be added on the 2nd load balancing decision, which may or may not be the original master server. This is easily solved with the cookie, as the persistence entry can be added on the HTTP_RESPONSE event. I'm struggling with the logic to :
1) On the response event, create persistence entry for cookie and URI
2) On the request event, if cookie persistence is used, delete the uri persistence entry and vice versa.
One follow-up. If you are setting both via uie persistence, and the value (jsessionid, either from cookie or link) is the same, does one get overwritten? I guess it doesn't matter, since the value will be matched when evaluted on the http_request event when persisted via the cookie value or the $jsess value. - Deb_Allen_18Historic F5 AccountFor setting the persistence entry on the response, the final rule in this post worked: (Click here) , although as noted, the server /can/ set more than one Set-Cookie header when setting multiple cookies, so you might need to do some additional coding to find it.
I've used variations on the theme for a couple of other customers since, for both ASP & jsession ID's, and it seems to do the trick. (We have not yet run into multiple Set-Cookie headers.)
You'd just need to add condtional logic in the request event to look for the cookie then fall back the URI if no cookie:
(of course adjusting the offset / length of findstr to match your cookie name & value lengths)if {[HTTP::cookie exists ASP.NET_SessionId] }{ set SessionId [HTTP::cookie ASP.NET_SessionId] else { set SessionId [HTTP::uri findstr "ASP.NET_SessionId=" 17 24] }
Since the cookie will be set by the server regardless of whether the client will ever use it, I think you're safe to exclusively extract the value from the Set-Cookie header, rather than from the payload.
Your last statement is correct. The request event /could/ conditionally use cookie persistence in the presence of the cookie, but since you're creating the uie persistence record, probably easier & more consistent to just use that. (Otherwise I think you might have to coordinate expiry of the cookie with expiry of the persistence record... not sure, I'll leave that for you to think through.)
HTH
/deb - JRahm
Admin
I am setting the persistence on the first server response for clients who disable cookies. For clients who enable cookies, is it better (read--more efficient) to persist them with cookie insert, or write the persistence for the jsessionid cookie into the rule I'm using to persist the cookie-disabled clients? If I stick with cookie insert, I can delete the persistence entry from the table for clients who return with cookies, and maintain the entries for clients who do not. If I use the jsessionid cookie, then I must maintain persistence entries for all clients. - Deb_Allen_18Historic F5 Account
Tough question... You could try it both ways under load with rule timing enabled to determine the most efficient approach.
If you delete the persistence entry for a cookie-enabled client, that would reduce the size of the persistence table, reducing memory footprint & CPU cycles to parse through it, but I'm not sure if that's a likely bottleneck.
If you were to delete the persistence entry for any request w/a cookie, you'd have to search for it in the persistence table on each such request, which would increase the CPU cycles required for rule processing, perhaps offsetting the advantage gained above.
Aside from that, I'd say using uie persistence with a defined timeout for both is more deterministic, since the timeout is managed locally, and also seems be more administratively efficient. With cookies w/expiry, client clock variations may skew the cookie timeout, and if you resort to session cookies instead, you would have different session management behaviour for the 2 sets of clients.
HTH
/deb - JRahm
Admin
The non-cookie persistence does not work unless I have oneconnect enabled. Is this by design? My rule:when HTTP_RESPONSE { if { [HTTP::cookie exists "JSESSIONID"] } { set trimID [lindex [split [HTTP::cookie "JSESSIONID"] "!" ] 0] if { [persist lookup uie $trimID] equals "" } { persist add uie $trimID 1800 log "added persistent entry $trimID for server [LB::server addr]" } else { log "continued sessionID $trimID for server [LB::server addr]" } } } when HTTP_REQUEST { if { [active_members MyPool] == 0 } { HTTP::redirect "http://[HTTP::header "X-Forwarded-Host"]/myUri.html" } if { [HTTP::header exists "X-Forwarded-Host"] } { HTTP::header replace "Host" [HTTP::header "X-Forwarded-Host"] } if { not [HTTP::cookie exists "MyCookie"] } { set jsess [findstr [HTTP::uri] "jsessionid" 11 "!"] if { $jsess != "" } { persist uie $jsess 1800 log "Used URI, value is $jsess, server [LB::server addr]" } } else { log "used Cookie Insert, value is [HTTP::cookie "MyCookie"]" } } - Deb_Allen_18Historic F5 AccountWithout OneConnect enabled, only the first request in a Keep-Alive connection is parsed for persistence data, so if multiple requests are sent on the same Keep-Alive connection, LTM will persist them all to the same destination as the first.
A OneConnect profile with mask of 255.255.255.255 will allow parsing of all requests and serverside connections will only be re-used for the same client.
HTH
/deb - Deb_Allen_18Historic F5 Accountfollow on post split to new topic: Click here
Help guide the future of your DevCentral Community!
What tools do you use to collaborate? (1min - anonymous)Recent Discussions
Related Content
DevCentral Quicklinks
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com
Discover DevCentral Connects
