Advice on Shira with FB Connect, Session Clustering Efficiency

Advice on Shira with FB Connect, Session Clustering Efficiency

Hi All,

I'm currently using Spring Security which until now was doing a fine job for my needs. Once we started doing session clustering w/o any session stickiness, we ran into issues with Spring Security. Specifically, it saves a lot of security related classes in the Session which makes Session serialization inefficient. Even more so, trying to use a performant serialization method like Kryo is difficult because of the not-so-POJO-friendly design of the Spring Security classes.

Anyway, Shiro seems like one good alternative and i've been studying it for the last day. My question concerns integration with Facebook Connect and Session usage.

Our site is Facebook Connect only so that is the only requirement for authentication. We do cross reference some user preferences for app speficic authorization information.

It seems like i'd need a custom filter to retrieve the Facebook credentials and a custom Realm that doesn't do much more than see if the user already exists in the store + some other roles logic.

So any help would be appreciated for helping me answer:

1. What is the ideal way anyone here has done this (i'm sure i'm not the first)?
2. I have some custom "login" logic to check if the user exists and create the user if not + some other locked status stuff. I assume this goes in the Realm?
3. What kind of data does Shiro actually save in the Session? We're very keen on keeping it as lean as possible and easily serializable using Kryo or other performant library (these libraries usually use default constructors and reflection).
4. We have some functionality that sends requests that don't contain the SessionID (from flash) so we just include the SessionID as a request parameter and "inject" the security context using a filter in the request thread. Is that possible with Shiro without doing a complete "login" process? It should allow Session lookup by id.

Re: Advice on Shira with FB Connect, Session Clustering Efficiency

Hi there,

> 1. What is the ideal way anyone here has done this (i'm sure i'm not the
> first)?

I have not done this, but yes, you would create a Realm and/or filter
as necessary to handle the Facebook Connect protocol. If you (or
someone) does this and wishes to contribute it back to the project,
please create a Jira issue!

> 2. I have some custom "login" logic to check if the user exists and create
> the user if not + some other locked status stuff. I assume this goes in the
> Realm?

You could do it there. I'd probably delegate that logic to a
component that plugs in to your Realm so you keep that logic separate
from the Realm's needs.

Then, once the user is authenticated (or authenticated and then
created), you return the identity you need in the form of a Shiro
AuthenticationInfo.

> 3. What kind of data does Shiro actually save in the Session? We're very
> keen on keeping it as lean as possible and easily serializable using Kryo or
> other performant library (these libraries usually use default constructors
> and reflection).

Very very little. Here are the session usages I can think of off the
top of my head:

1. By default it will store the PrincipalCollection (the collection of
account identities discovered during authentication) after login so
the Subject's identity is available for the remainder of the session.

2. It will use the session to store a request if the request needs to
be redirected and referenced later. For example, if an
unauthenticated user visits an authentication-required page, they
could be redirected to the login page. Before redirect, the request
will be saved in the session so that after successful login, Shiro can
auto-redirect the user back to the same page they originally
requested.

3. During 'runAs' functionality. RunAs is implemented as a stack of
PrincipalCollections that get pushed on or popped off of the stack as
runAs identities are accumulated or released, respectively. That
stack is presently stored in the Subject's session if runAs
functionality is engaged. If runAs is not used, the session is not
touched.

I think that's it. To ensure that sessions are clustered as
efficiently as possible, ensure that the PrincipalCollection returned
from your Realm during authentication is as lean as possible. Most
people store a primitive value that is a 'pointer' to the actual data
- e.g. a user id or username or similar - to ensure the session
remains lean.

> 4. We have some functionality that sends requests that don't contain the
> SessionID (from flash) so we just include the SessionID as a request
> parameter and "inject" the security context using a filter in the request
> thread. Is that possible with Shiro without doing a complete "login"
> process? It should allow Session lookup by id.

Absolutely! Shiro's session support really shines for these types of
'frameworky' issues.

You will need to replicate what the ShiroFilter does for web requests:
when encountering a session ID associated with the request, build a
Subject instance that corresponds to the referenced session and ensure
the Subject is bound to the thread for access at any time during the
thread's execution. This is trivial w/ the Shiro APIs:

I know people have already done this to support Shiro in the SmartFox
Server for Flash-based mmo games, but I don't know where the code is.
If you can find it, that might help as well. In any event, I'm sure
that code looks like the above two code samples, so they might get you
far enough.

> 1. What is the ideal way anyone here has done this (i'm sure i'm not the
> first)?

I have not done this, but yes, you would create a Realm and/or filter
as necessary to handle the Facebook Connect protocol. If you (or
someone) does this and wishes to contribute it back to the project,
please create a Jira issue!

> 2. I have some custom "login" logic to check if the user exists and create
> the user if not + some other locked status stuff. I assume this goes in the
> Realm?

You could do it there. I'd probably delegate that logic to a
component that plugs in to your Realm so you keep that logic separate
from the Realm's needs.

Then, once the user is authenticated (or authenticated and then
created), you return the identity you need in the form of a Shiro
AuthenticationInfo.

> 3. What kind of data does Shiro actually save in the Session? We're very
> keen on keeping it as lean as possible and easily serializable using Kryo or
> other performant library (these libraries usually use default constructors
> and reflection).

Very very little. Here are the session usages I can think of off the
top of my head:

1. By default it will store the PrincipalCollection (the collection of
account identities discovered during authentication) after login so
the Subject's identity is available for the remainder of the session.

2. It will use the session to store a request if the request needs to
be redirected and referenced later. For example, if an
unauthenticated user visits an authentication-required page, they
could be redirected to the login page. Before redirect, the request
will be saved in the session so that after successful login, Shiro can
auto-redirect the user back to the same page they originally
requested.

3. During 'runAs' functionality. RunAs is implemented as a stack of
PrincipalCollections that get pushed on or popped off of the stack as
runAs identities are accumulated or released, respectively. That
stack is presently stored in the Subject's session if runAs
functionality is engaged. If runAs is not used, the session is not
touched.

I think that's it. To ensure that sessions are clustered as
efficiently as possible, ensure that the PrincipalCollection returned
from your Realm during authentication is as lean as possible. Most
people store a primitive value that is a 'pointer' to the actual data
- e.g. a user id or username or similar - to ensure the session
remains lean.

> 4. We have some functionality that sends requests that don't contain the
> SessionID (from flash) so we just include the SessionID as a request
> parameter and "inject" the security context using a filter in the request
> thread. Is that possible with Shiro without doing a complete "login"
> process? It should allow Session lookup by id.

Absolutely! Shiro's session support really shines for these types of
'frameworky' issues.

You will need to replicate what the ShiroFilter does for web requests:
when encountering a session ID associated with the request, build a
Subject instance that corresponds to the referenced session and ensure
the Subject is bound to the thread for access at any time during the
thread's execution. This is trivial w/ the Shiro APIs:

I know people have already done this to support Shiro in the SmartFox
Server for Flash-based mmo games, but I don't know where the code is.
If you can find it, that might help as well. In any event, I'm sure
that code looks like the above two code samples, so they might get you
far enough.

Re: Advice on Shira with FB Connect, Session Clustering Efficiency

On Mon, Sep 26, 2011 at 10:32 AM, matan_a <[hidden email]> wrote:
> It seems like i'd need a custom filter to retrieve the Facebook credentials
> and a custom Realm that doesn't do much more than see if the user already
> exists in the store + some other roles logic.

Based on that I'm assuming you are currently using fb.login or
similar, purely client-side integration.
> So any help would be appreciated for helping me answer:
> 1. What is the ideal way anyone here has done this (i'm sure i'm not the
> first)?

> 2. I have some custom "login" logic to check if the user exists and create
> the user if not + some other locked status stuff. I assume this goes in the
> Realm?
> 3. What kind of data does Shiro actually save in the Session? We're very
> keen on keeping it as lean as possible and easily serializable using Kryo or
> other performant library (these libraries usually use default constructors
> and reflection).
> 4. We have some functionality that sends requests that don't contain the
> SessionID (from flash) so we just include the SessionID as a request
> parameter and "inject" the security context using a filter in the request
> thread. Is that possible with Shiro without doing a complete "login"
> process? It should allow Session lookup by id.
>
> Thanks in advance and again, much appreciated!
>
> --
> View this message in context: http://shiro-user.582556.n2.nabble.com/Advice-on-Shira-with-FB-Connect-Session-Clustering-Efficiency-tp6832777p6832777.html> Sent from the Shiro User mailing list archive at Nabble.com.
>