Hi Les!

Thanks for this wealth of information! I'll detail my experiments below:

1) I made my principal lazy, i.e. it only contains an UUID and loads everything 
from the DB as required. This shaved off about 30%, but it still left about 700 
bytes.
2) Turning off encryption isn't a biggie, it only reduced the cookie size a few 
tens of bytes, so I turned it back on.
3) I wrote my own Serializer, and this was the whopper: just by simply 
serializing nothing but the UUID (with the appropriate magic numbers), I was 
able to squeeze the cookie size from 700 bytes to 74 bytes (!) while encryption 
was on. This is a good result, and should also make my website a bit snappier 
since there is no longer a need to transfer huge cookies.  This suggests that 
the default HashMap serialization *is* actually a lot of overhead for simple 
usecases, and it might be a good idea to figure out something lighter.

Considering that I have only a single Realm with a single Principal, I assume 
that doing stuff like this is safe? Shiro never adds any principals on its own 
to the PrincipalCollection? Are there any events in which I would have 
Principals I did not control?

/Janne

On Dec 12, 2010, at 00:44 , Les Hazlewood wrote:

> Hi Janne,
> 
> The CookieRememberMeManager and it's parent abstract class
> AbstractRememberMeManager are pretty 'pluggable' - you probably won't
> need to implement a new subclass.
> 
> The default behavior is the following:
> 
> 1.  Serialize the Subject.getPrincipals() (PrincipalCollection) into a
> byte array
> 2.  If there is a CipherService present (and there is by default - an
> AesCipherService), encrypt the byte array from step 1, resulting in a
> new byte array
> 3.  Take the resulting byte array, base64 encode it, and set that
> base64-encoded value as the cookie value.
> 
> If a Subject's PrincipalCollection is large, step 1 could result in a
> larger byte array.  Step 2 may or may not make it larger, depending on
> the data.  Byte arrays have to be base64 encoded for web use, so you
> may not be able to get around step 3.
> 
> By default, the AbstractRememberMeManager has a
> Serializer<PrincipalCollection> that defaults to an
> org.apache.shiro.io.DefaultSerializer.  This performs default Java
> object serialization and serializes what is usually an
> org.apache.shiro.subject.SimplePrincipalCollection.  The
> SimplePrincipalCollection implements the Java serialization's
> 'writeObject' and 'readObject' methods, but they just delegate to
> serializing the backing LinkedHashMap.  This is pretty efficient as
> long as the principals you store in the PrincipalsCollection are small
> and serialize efficiently themselves.
> 
> For example, it is a bad idea to store an entire User object in the
> PrincipalCollection returned from a Realm after login.  Ideally a
> principal should be a primitive 'pointer' of sorts - a long, a UUID, a
> short string, etc that is used to look up the user later.  I would
> check on this before doing anything else.
> 
> If the default PrincipalCollection serialization approach doesn't work
> well for you, you can inject your own Serializer<PrincipalCollection>
> into your CookieRememberMeManager implementation.
> 
> Also note that encrypting the principal collection is an added
> security benefit.  If you don't want to do this because you feel that
> the remember me identity doesn't constitute sensitive information,
> then you can set the CipherService to null, at which point the data
> won't be encrypted.
> 
> Unfortunately I just discovered that you can't set a null value in
> shiro.ini, e.g.:
> 
> [main]
> ...
> securityManager.rememberMeManager.cipherService = null
> 
> This won't work.
> 
> I've created an issue https://issues.apache.org/jira/browse/SHIRO-225
> to get this to work.  However, until then, you'll probably need to do
> this programatically:
> 
> ((CookieRememberMeManager)securityManager.getRememberMeManager()).setCipherService(null);
> 
> Again, this is only if you think the encryption operation is causing
> your byte array to be much larger than expected and you don't feel
> that encryption is necessary.
> 
> A simple test would be to see what the byte array size is using all of
> Shiro's defaults (e.g. in a debugger).  Then set the cipherService to
> null and see what size the byte array is then.  I'd love to hear what
> you find - please let us know!
> 
> Anyway, I hope this helps!
> 
> Cheers,
> 
> Les
> 
> On Sat, Dec 11, 2010 at 4:17 AM, Janne Jalkanen
> <[email protected]> wrote:
>> Hi!
>> 
>> Noticed something strange - as of last night my time, it appears that I 
>> cannot use the CookieRememberMeManager with AWS Elastic Load Balancing.
>> 
>> All requests when you have RememberMe cookie set fail with either 400 Bad 
>> Request or 505 HTTP Version Not Supported.
>> 
>> Any ideas how to debug this? Resulting cookie too big for ELB? Is there a 
>> nice way to reduce the cookie size or do I have to write my own 
>> RememberMeManager?
>> 
>> (This is with Shiro 1.1.0 release.)
>> 
>> /Janne

Reply via email to