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
