Yep, you're exactly right - it is because of the new (more secure)
CipherService instances.  I would ignore these warnings - the
rememberMe cookie will be deleted and a new correct one will be
auto-created the next time they log in (and they click 'remember me'
of course).

If you didn't want to ignore them and have them just work, you can do 3 things:

1.  Configure the RememberMeManager to use the BlowfishCipherService.
Prior to the 1.0 release, we defaulted to using the Blowfish
algorithm, but most people prefer AES, so now we default to the
AesCipherService.
2.  Ensure that the new BlowfishCipherService is using the _exact_
same key that was used before.  This is simple if you're using your
own cipher key.  It is harder if you were using Shiro's default
blowfish key, at which point you would need to look at the old source
code to find it.
3.  Ensure that your BlowfishCipherService instance's
'generateInitializationVectors' attribute is set to false.

Step 3 makes the encryption less secure and overall 1-3 can be a pain.
 I'd recommend just ignoring the warnings for now and let the new
cookies replace the old ones if you are ok with that.

One thing you might want to try is using your own cipher key with the
CipherService instance - it makes it more secure instead of using
Shiro's default (which could be discovered by a 3rd party).  To be
fair, the encrypted data is just a serialized PrincipalCollection, so
if you're not storing sensitive data in the PC, you don't really need
to do this.  I still like to do it though in case I ever do need to
use an AES Cipher to encrypt something sensitive - then my key is all
ready to go.

You can do this by doing the following:

//AES algorithm only supports key sizes of 128, 192, and 256 bits.
//192 and 256 require that the JCE Unlimited Strength
//Jurisdiction Policy files to be installed.
int keySize = 128;
String key = Base64.encode(new
AesCipherService().generateNewKey(keySize).getEncoded());

//then you can use this key in your shiro config:

[main]
securityManager.rememberMeManager.cipherKey =
your_base64_encoded_string_from_above

The configurator will automatically recognize that is a byte array
property and Base64 decode the string value into the correct bytes.
If you wanted to use Hex encoding instead, make sure you prefix your
encoded string with 0x ('zero' 'x'):

securityManager.rememberMeManager.cipherKey = 0x123456789ABCDEF

which will trigger Hex decoding instead.

I know I've rambled on about this, but hopefully this will be indexed
by Google and help someone else in the future.  It also gives me a
base to use to update the wiki documentation :)

Cheers,

Les

1.  Ensure that the cipher service is using the same cipher key
you could configure your CipherService to set
'generateInitializationVectors' to false, in which case the previou

On Wed, May 12, 2010 at 11:08 AM, Tauren Mills <[email protected]> wrote:
> Also, I'm getting the following exception in my logs. I'm assuming that is
> just because people have old cookies with old cyphers, and that once their
> cookies are replaced, I won't see these exceptions anymore. I also assume
> this means that everyone is being forced to log in again since my app has
> been updated with the latest shiro and that no existing rememberme cookies
> will work.  Is this correct?
> Thanks,
> Tauren
> ---
>
> WARN  - DefaultSecurityManager     - Delegate RememberMeManager instance of
> type [com.project.security.MyRememberMeManager] threw an exception during
> getRememberedPrincipals().
> org.apache.shiro.crypto.CryptoException: Unable to execute 'doFinal' with
> cipher instance [javax.crypto.cip...@5b3bd1c0].
> at org.apache.shiro.crypto.JcaCipherService.crypt(JcaCipherService.java:465)
> at org.apache.shiro.crypto.JcaCipherService.crypt(JcaCipherService.java:448)
> at
> org.apache.shiro.crypto.JcaCipherService.decrypt(JcaCipherService.java:393)
> at
> org.apache.shiro.crypto.JcaCipherService.decrypt(JcaCipherService.java:385)
> at
> org.apache.shiro.mgt.AbstractRememberMeManager.decrypt(AbstractRememberMeManager.java:491)
> at
> org.apache.shiro.mgt.AbstractRememberMeManager.convertBytesToPrincipals(AbstractRememberMeManager.java:431)
> at
> org.apache.shiro.mgt.AbstractRememberMeManager.getRememberedPrincipals(AbstractRememberMeManager.java:398)
> at
> com.project.security.MyRememberMeManager.getRememberedPrincipals(MyRememberMeManager.java:21)
> at
> org.apache.shiro.mgt.DefaultSecurityManager.getRememberedIdentity(DefaultSecurityManager.java:526)
> at
> org.apache.shiro.mgt.DefaultSecurityManager.resolvePrincipals(DefaultSecurityManager.java:403)
> at
> org.apache.shiro.mgt.DefaultSecurityManager.createSubject(DefaultSecurityManager.java:320)
> at org.apache.shiro.subject.Subject$Builder.buildSubject(Subject.java:767)
> at
> org.apache.shiro.web.subject.WebSubject$Builder.buildWebSubject(WebSubject.java:101)
> at org.apache.shiro.web.servlet.ShiroFilter.bind(ShiroFilter.java:540)
> at
> org.apache.shiro.web.servlet.ShiroFilter.doFilterInternal(ShiroFilter.java:627)
> at
> org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:83)
> at
> org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1088)
> at
> org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198)
> at
> org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
> at
> org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1088)
> at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:360)
> at
> org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
> at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
> at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:729)
> at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405)
> at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
> at org.mortbay.jetty.Server.handle(Server.java:324)
> at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:505)
> at
> org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:829)
> at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:513)
> at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:211)
> at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:380)
> at
> org.mortbay.jetty.bio.SocketConnector$Connection.run(SocketConnector.java:228)
> at
> org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:488)
> Caused by: javax.crypto.BadPaddingException: Given final block not properly
> padded
> at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
> at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
> at com.sun.crypto.provider.AESCipher.engineDoFinal(DashoA13*..)
> at javax.crypto.Cipher.doFinal(DashoA13*..)
> at org.apache.shiro.crypto.JcaCipherService.crypt(JcaCipherService.java:462)
> ... 33 more
>
> On Wed, May 12, 2010 at 9:49 AM, Tauren Mills <[email protected]> wrote:
>>
>> Les,
>> Thanks for the help.  However, now I'm having a problem
>> with getRememberedPrincipals() being called dozens of times per page
>> view, causing my "accessed" property to be updated many times, which is
>> obviously not ideal.
>> I believe this is because my application is running in Jetty, so every
>> image, JS, CSS, and other resource is causing a request to be created. My
>> cookie is set to / since I need it to work for many different paths.
>> Any suggestions on how to only update my "accessed" property a single time
>> per session?  I don't need the property updated with every request, just
>> when they first access the site for a session is fine.  Basically, the
>> property I currently called "accessed" would actually be more accurately
>> called "lastLogin".
>> Below is code if it helps.
>> Thanks,
>> Tauren
>> ---
>> public class MyRememberMeManager extends CookieRememberMeManager {
>> private MemberService memberService;
>>    �...@autowired
>> public void setMemberService(MemberService memberService) {
>> this.memberService = memberService;
>> }
>> @Override
>> public PrincipalCollection getRememberedPrincipals(SubjectContext
>> subjectContext) {
>> PrincipalCollection principals =
>> super.getRememberedPrincipals(subjectContext);
>> if ( principals != null ) {
>> Long id = (Long) principals.getPrimaryPrincipal();
>> memberService.updateAccessed(id);
>> }
>> return principals;
>> }
>> }
>> // MemberServiceImpl.java
>> public void updateAccessed(Long id) {
>> updateAccessed(findById(id));
>> }
>> public void updateAccessed(Member member) {
>> member.setAccessed(new Date());
>> memberDao.save(member);
>> }
>>
>> // Spring config
>>     <bean id="securityManager"
>> class="org.apache.shiro.web.DefaultWebSecurityManager">
>>       property instead. -->
>>         <property name="realm" ref="myRealm"/>
>>         <property name="rememberMeManager" ref="myRememberMeManager"/>
>>     </bean>
>>     <bean name="myRememberMeManager"
>> class="com.project.security.MyRememberMeManager"/>
>>
>> On Tue, May 11, 2010 at 10:11 AM, Les Hazlewood <[email protected]>
>> wrote:
>>>
>>> Hi Tauren,
>>>
>>> Yes, WebRememberMeManager has been deprecated in favor of the new
>>> CookieRememberMeManager which uses a new Cookie property and not the
>>> (now deprecated) CookieAttribute concept.  CookieAttribute was complex
>>> and confusing.  The new Cookie interface and implementation in
>>> comparison are much easier to understand and configure.  So, if you
>>> extend CookieRememberMeManager, you should be closely back to where
>>> you were when you extended WebRememberMeManager.
>>>
>>> As for the SubjectContext - it was added within the last two weeks to
>>> satisfy a technical requirement: the (now new) SubjectContext.resolve*
>>> method behavior was needed in multiple places across more than one OO
>>> hierarchy.  So, we either had to copy-n-paste logic (yuck) or
>>> consolidate it into a component.  The SubjectContext satisfies this
>>> need and will stay in place instead of the raw Map.
>>>
>>> Also note that for 1.0, we'll be removing all Deprecated classes and
>>> methods.  Since we're wrapping up coding issues today (and possibly
>>> tomorrow), we'll be deleting them any time now.
>>>
>>> I hope that helps!
>>>
>>> Les
>>>
>>> On Tue, May 11, 2010 at 9:22 AM, Tauren Mills <[email protected]> wrote:
>>> > I'm just getting back to this issue now, and have updated to the latest
>>> > shiro snapshot.
>>> > When I started working on this, I had extended WebRememberMeManager,
>>> > but it
>>> > looks like it is now depricated. What is the recommended approach at
>>> > this
>>> > time? Should I be directly extending AbstractRememberMeManager?
>>> > I also wanted to point out that your example in this thread shows
>>> > passing a
>>> > Map to getRememberedPrincipals, but in my experience I had to pass a
>>> > SubjectContext.  Before I proceed further, I just want to make sure
>>> > that I'm
>>> > heading down the proper path that will be supported in the future, and
>>> > not
>>> > implement something that I'll have to change later.
>>> > Thanks!
>>> > Tauren
>>> >
>>> >
>>> >
>>> >
>>> >
>>> >
>>> > On Mon, Apr 19, 2010 at 12:14 PM, Les Hazlewood <[email protected]>
>>> > wrote:
>>> >>
>>> >> I committed a change to how cryptography works on Friday - that might
>>> >> have done something with it (we encrypt principals by default).
>>> >> However, all the test cases still passed and I know that we do have
>>> >> some test cases around remember me cookies (WebRememberMeManagerTest).
>>> >>
>>> >> Please open a Jira issue in the mean time so we don't lose it.  I'll
>>> >> try to run the sample web app(s) to see if they exhibit the same
>>> >> behavior.
>>> >>
>>> >> Thanks!
>>> >>
>>> >> Les
>>> >>
>>> >> On Mon, Apr 19, 2010 at 10:57 AM, Tauren Mills <[email protected]>
>>> >> wrote:
>>> >> > It seems that my remember me function got broken at some point. All
>>> >> > of
>>> >> > my
>>> >> > requests do not have the cookie they used to. I've tried logging off
>>> >> > and
>>> >> > back in again, but still no cookie.  This is
>>> >> > causing getRememberedPrincipals
>>> >> > to run with every single request. Obviously not good.
>>> >> > Any suggestions on how to track down where the remember me problem
>>> >> > is
>>> >> > coming
>>> >> > from - why I'm not getting cookies? I haven't done much of anything
>>> >> > with
>>> >> > Shiro for months now, and it used to work, so not sure what
>>> >> > happened.
>>> >> > Was it
>>> >> > broken in some recent release that I may be using?
>>> >> > Thanks,
>>> >> > Tauren
>>> >> > On Mon, Apr 19, 2010 at 3:41 AM, Tauren Mills <[email protected]>
>>> >> > wrote:
>>> >> >>
>>> >> >> Les,
>>> >> >> Thanks, I'll look into doing this. Are there any examples of using
>>> >> >> an
>>> >> >> AuthenticationListener that I could reference?
>>> >> >>
>>> >> >> Tauren
>>> >> >>
>>> >> >> On Fri, Apr 16, 2010 at 9:10 AM, Les Hazlewood
>>> >> >> <[email protected]>
>>> >> >> wrote:
>>> >> >>>
>>> >> >>> Hi Tauren,
>>> >> >>>
>>> >> >>> You could implement an AuthenticationListener - I typically like
>>> >> >>> to do
>>> >> >>> this for these kinds of operations.
>>> >> >>>
>>> >> >>> Since Shiro does not count remember me as a true authentication,
>>> >> >>> the
>>> >> >>> AuthenticationListener will not be triggered for remember me
>>> >> >>> events.
>>> >> >>> To do that you would also need to implement your own
>>> >> >>> RememberMeManager.  Typically subclassing the default one and
>>> >> >>> updating
>>> >> >>> the timestamp in the getRememberedPrincipals method would work:
>>> >> >>>
>>> >> >>> @Override
>>> >> >>> public PrincipalCollection getRememberedPrincipals(Map
>>> >> >>> subjectContext)
>>> >> >>> {
>>> >> >>>    PrincipalCollection principals =
>>> >> >>> super.getRememberedPrincipals(subjectContext);
>>> >> >>>    if ( principals != null ) {
>>> >> >>>        int userId = principals.getPrimaryPrincipal();
>>> >> >>>        //update the last login timestamp for user with this id
>>> >> >>> here
>>> >> >>>    }
>>> >> >>> }
>>> >> >>>
>>> >> >>> The above method is called only if the current Subject/session
>>> >> >>> does
>>> >> >>> not yet have an identity associated with it.
>>> >> >>>
>>> >> >>> The AuthenticationListener + the above overridden method should do
>>> >> >>> it!
>>> >> >>>
>>> >> >>> Cheers,
>>> >> >>>
>>> >> >>> Les
>>> >> >>>
>>> >> >>> On Thu, Apr 15, 2010 at 8:37 PM, Tauren Mills <[email protected]>
>>> >> >>> wrote:
>>> >> >>> > What would be the best way to update properties of a member on
>>> >> >>> > successful
>>> >> >>> > authentication? Basically, there is a Member.lastLogin property
>>> >> >>> > that
>>> >> >>> > I
>>> >> >>> > want
>>> >> >>> > updated with the current date every time a member comes back to
>>> >> >>> > a
>>> >> >>> > site
>>> >> >>> > and
>>> >> >>> > logs in.  However, this should also support rememberme
>>> >> >>> > authentications. I
>>> >> >>> > don't necessarily want to update the lastLogin property on every
>>> >> >>> > single
>>> >> >>> > interaction the user has on the site, just once for each
>>> >> >>> > session.
>>> >> >>> > Is there some technique in Shiro to do this, a callback of some
>>> >> >>> > sort,
>>> >> >>> > or
>>> >> >>> > some other method? Or should I be doing this in my application?
>>> >> >>> > Also, I can't seem to view much of the documentation. All the
>>> >> >>> > links
>>> >> >>> > on
>>> >> >>> > the
>>> >> >>> > following page require an Apache login. Is it supposed to be
>>> >> >>> > this
>>> >> >>> > way?
>>> >> >>> > http://incubator.apache.org/shiro/core.html
>>> >> >>> > Thanks!
>>> >> >>> > Tauren
>>> >> >>> >
>>> >> >>> >
>>> >> >>
>>> >> >
>>> >> >
>>> >
>>> >
>>
>
>

Reply via email to