The Shibboleth IdP V3 software has reached its End of Life and is no longer supported. This documentation is available for historical purposes only. See the IDP4 wiki space for current documentation on the supported version.

Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

Version 1 Next »

Work in progress document on design of Sessions in the IdP.

IdPSession

What we're maybe storing:

  • an ID
  • secret (replace with V4 and V6 address, per below)
  • creation time
  • last activity time
  • canonical principal name
  • map of flow ID to AuthenticationResult
  • map of SP entityID to ServiceSession

I think the secret is irrelevant. V2 uses session cookies that are MAC'd with the secret and contain V4 and V6 client addresses. This is more complex than we need, we can just replace the secret with the two addresses and use a highly random ID in the session cookie like the SP does.

A client side session probably doesn't need an ID strictly speaking but we probably want it for logging / auditing.

If we don't use a multi-map then each type of authentication configured would be tracked only once per session, so reuse of a method might replace the older copy. This seems ok, probably, and avoids the problem of garbage collection of older results.

ServiceSession

What we're maybe storing:

  • ID of service
  • maybe a creation time, do we care?
  • thinking we might track an expiration, otherwise how do we bound the number of these?
  • flow ID used for service (could be fresh, or a reuse of active result derived from flow)
  • for SAML at least, we would need the NameID issued in the transaction to be able to propagate logout

The latter is a bitch, because we don't have it until very late in the flow. Thinking this means we don't want to actually update the session until very late (or at least not write it back to storage, which is what update really means in this context).

We're storing custom Principals to handle SAML-specific stuff elsewhere, maybe we create custom ServiceSession types with additional data tracked. This might help allow for heterogenous sessions with different protocols used with particular SPs. I know we didn't want hierarchies, but this feels more like data modeling to me, and it's just one deep.

Storage

Pretty well decided that we have two modes, client-side and server-side. Client-side means we don't store the ServiceSessions, but try to fit the rest. Obviously this makes logout completely impossible. Even if we work around the problem of not having access to the session when the request comes in, we will never have the data needed to propagate the logout. We discussed splitting the storage model up so that anything needed for logout would be managed by a separate StorageService instance that would have to be non-client-side.

Lookup Requirements

Main one obviously is lookup via client delivering session or client cookie with key to session, latter requiring basic index by session ID. Note: validation of a session's use is a separate issue. We are not going to overload lookup with validation.

V2 supports lookups in conjunction with queries. I'm very reluctant to support this because it's ambiguous; a non-transient NameID could map to multiple Sessions and I'm not sure that's helpful, but if we do it, I think we have to expose all of them. Also, the query lookups for a session are done based on the principal name after reversing the NameID. I think we should dump this, it's superfluous if we index by NameID. We didn't used to index by NameID in V2, so that's probably why it was done that way.

Logout requires a lookup by SP, NameID, and optional SessionIndex. With no SessionIndex, we definitely have to handle multiple Sessions coming back by design. The use case for non-indexed logout was about terminating sessions with multiple devices. With a SessionIndex, we should only get a single one back.

So we have:

Session ID -> Session (1:1)

SP + NameID -> Session (1:N)

SP + NameID + SAML SessionIndex -> Session (1:1)

Indexing

With the SP, I don't try and turn the NameID, etc. into a fully unique key, just a mostly unique one. I just index by a possibly truncated version of the NameID value, ignoring the qualifiers. Then I validate the results I get back and check for an exact match using the content of the Session before I include it in the set returned.

The StorageService API I have used doesn't accomodate secondary indexing natively. In the SP, I built a secondary index by maintaining a list of the session IDs mapped to the index key. The cleanup problem is dodged there by not doing it. This works to a point under two conditions:

  • there's an upper bound on lifetime of the session, which puts an upper bound on the life of the list of sessions indexed by a given key
  • there aren't a huge number of sessions to be indexed by one key that would make reading and writing the list inefficient

The second of these is a problem for load testing because it can generate a huge number of sessions for a single NameID. This is pretty easy to workaround by having an option not to do the indexing, which is not needed when load testing anyway. I have never come across a legitimate scenario outside of load tests where the number would get large enough to be such a problem.

Right now, I don't think we know about the upper bound question. V2 doesn't bound the IdP session lifetime, because the individual login methods do get lifetimes, and that's also true in V3. And adding one doesn't seem to work very well, since it creates a hard stopping point that would dump all existing active results and force new authentication, even if the user literally logged in again seconds before. The mixing of the IdP session and the AuthnResult object lifetimes and policies to handle SSO create a disincentive for having a real "lifetime" on the session.

So the lack of an upper bound seems like the bigger problem. We can't maintain a secondary index in a naive way that lacks cross-index coherency if there's no way to know when to blow away the index as a worst case. About all we could do is implement background cleanup to walk the indexed lists of sessions, and that would take way too many individual storage lookups. So, hmm.

 

  • No labels