Remembered vs. Authenticated
As shown in the example above, Shiro supports the notion of “remember me” in addition to the normal login process. It is worth pointing out at this time that Shiro makes a very precise distinction between a remembered Subject and an actual authenticated Subject:
-
Remembered: A remembered
Subject
is not anonymous and has a known identity (i.e.subject.
getPrincipals()
is non-empty). But this identity is remembered from a previous authentication during a previous session. A subject is considered remembered ifsubject.
isRemembered()
returnstrue
. -
Authenticated: An authenticated
Subject
is one that has been successfully authenticated (i.e. thelogin
method was invoked without throwing an exception) during the Subject’s current session. A subject is considered authenticated ifsubject.
isAuthenticated()
returnstrue
.
Mutually Exclusive
Remembered and authenticated states are mutually exclusive - a true
value for one indicates a false
value for the other and vice versa.
Why the distinction?
The word ‘authentication’ has a very strong connotation of proof. That is, there is an expected guarantee that the Subject
has proven they are who they say they are.
When a user is only remembered from a previous interaction with the application, the state of proof no longer exists: the remembered identity gives the system an idea who that user probably is, but in reality, has no way of absolutely guaranteeing if the remembered Subject represents the expected user. Once the subject is authenticated, they are no longer considered only remembered because their identity would have been verified during the current session.
So although many parts of the application can still perform user-specific logic based on the remembered principals, such as customized views, it should typically never perform highly-sensitive operations until the user has legitimately verified their identity by executing a successful authentication attempt.
For example, a check to see if a Subject
can access financial information should almost always depend on isAuthenticated()
, not isRemembered()
, to guarantee an expected and verified identity.
An illustrating example
The following is a fairly common scenario that helps illustrate why the the distinction between remembered and authenticated is important.
Let’s say you’re using Amazon.com. You’ve logged-in successfully and have added a few books to your shopping cart. But you have to run off to a meeting, but forget to log out. By the time the meeting is over, it’s time to go home and you leave the office.
The next day when you come in to work, you realize you didn’t complete your purchase, so you go back to amazon.com. This time, Amazon ‘remembers’ who you are, greets you by name, and still gives you some personalized book recommendations. To Amazon, subject.isRemembered()
would return true
.
But, what happens if you try to access your account to update your credit card information to make your book purchase? While Amazon ‘remembers’ you (isRemembered()
== true
), it cannot guarantee that you are in fact you (for example, maybe a co-worker is using your computer).
So before you can perform a sensitive action like updating credit card information, Amazon will force you to login so they can guarantee your identity. After you login, your identity has been verified and to Amazon, isAuthenticated()
would now be true
.
This scenario happens so frequently for many types of applications, so the functionality is built in to Shiro so you can leverage it for your own application. Now, whether you use isRemembered()
or isAuthenticated()
to customize your views and workflows is up to you, but Shiro will maintain this fundamental state in case you need it.