4

i am implmenting the java shiro for security.i need to return the message when session is expired and if session is not expired then i need to return different message like un Authenticate user.

This is my code.

@GET
@Path("/{userId}")
public Response view(@PathParam("userId")String userId)
{
   ResponseBuilder builder = Response.ok();
   if(SecurityUtils.getSubject().isAuthenticated())
    {

       Registeration registeration=new Registeration();
       boolean status=registeration.getDetails(userId,builder);
       log.debug("the status is:"+status); 


    }
    else
    {
        builder.status(401).entity("You are currently not login .please Login for Access Services");

    }   
    return builder.build();     

}

This above rest services working fine.when user is not login .this method will return the message of else part. but i need to return message also that after session had expired and user try to access this rest services then i need to return the "your session had expired " . but in above case if session is expired then also same message and the if user is not login then also same message. i do not know that how i will check this both condition that 1)if user is not login then message="you are login" 2)if session had expired then messsage="you session had expired"

user2549122
  • 203
  • 1
  • 5
  • 18

1 Answers1

2

After performed some simple testing, I believe that the way using SecurityUtils.getSubject().isAuthenticated() cannot get the correct result when the current session is timeout. I guess it works for you since the 2nd request created another Subject for you instead of the original one. This can be easily proved by acquiring it by ThreadContext.getSubject() instead of SecurityUtils.getSubject() since the latter create a new Subject for you if it is null. If the 2nd time a request reach to your method and the return value of ThreadContext.getSubject() is null, that means it's a new connection with a new thread to Shiro.

So, my testing turns out that if it's a 'timeout' case, Subject.isAuthenticated() will still return true. Note their document Session Validation & Scheduling :

For performance reasons, Sessions are only validated to see if they have been stopped or expired at the time they are accessed (i.e. subject.getSession()). This means that without additional regular periodic validation, Session orphans would begin to fill up the session data store.

For your requirement, you can implement a SessionListener and record the principal in method onExpiration. Or you can access the session to trigger the validation in Shiro:

if(SecurityUtils.getSubject().isAuthenticated()) {
    Session session = SecurityUtils.getSubject().getSession(false);
    try {
        session.touch();
    } catch (ExpiredSessionException e) {
        // timeout case.
    }
} else {
    // not login case.
}

Calling session.touch() is not redundant since it will update lastAccessTime which will not do so if you never touch session in you code.

Tatera
  • 448
  • 3
  • 11