A couple of things stick out:

1.) You shouldn't need to call `subject.login()` directly.  This is almost
always handled by some framework for you (like the Shiro Servlet Filter).
The same can be said for `.logout()` though to a lesser extent.
2.) As for the "logout" issue, I think this is a misuse of logout.

If you truly don't have any session/state, then the "logout" doesn't
_really_ have anything to clean up (like a session cache, or container
related session)
You _shouldn't_ be logging a user out if you expect the subject to remain
active (as you still need the context of the given subject).  My guess
(based on minimal data) is that you are forcing a logout, because you are
also managing the "login"?


Things get a little tricky when you with async tasks though, and the best
solution might depend on what you do when the processing is done.  Are you
emailing the user some results?  Does the user poll an endpoint until the
job is finished?

If the user does need to logout (and I can see some valid use cases for
this anyway, for example, If the job runs for 3 hours and the result is
emailed to the user) then there is no reason for a subject to be kept
alive.
There are a few ways to work around this, but can you give us some details
on your async task? And why you are calling login/logout? (Maybe because
you don't have a custom Filter?
https://shiro.apache.org/web.html#Web-DefaultFilters)

NOTE: Shiro 1.5 will contain support for Bearer tokens headers
<https://github.com/apache/shiro/blob/master/web/src/main/java/org/apache/shiro/web/filter/authc/BearerHttpAuthenticationFilter.java>
which may make your life easier too.


On Thu, Nov 28, 2019 at 7:38 AM otter606 <[email protected]> wrote:

> Hello
>  We have happily been using Shiro for some years now for our Spring MVC web
> application authentication and authorisation using standard Shiro filters
> to
> login and logout users.
> Recently we implemented an asynchronous 'export' feature where a request
> launches a background thread to perform a possibly long running ( a few
> minutes) task. The request returns a job ID that the client app can use to
> interrogate progress.  We bind the Subject to the Callable using <code>task
> = subject.associateWith(task);</code> and it all works fine, as in the web
> application the user generally remains logged in while the export is
> happening.
>
> We now expose this export feature through an API. Here is where we get a
> problem, maybe we are not using Shiro correctly here.
>  - We have implemented a Realm that checks for access token validity
>  - we have set noSessionCreation to be active as the API requests are
> supposed to be stateless
> - if all ok we call SecurityUtils.getSubject().login so that there is an
> authenticated principal to do permissions checks on access to resources
> that
> are going to be exported.
> - When the API call is finished, in a filter we call
> SecurityUtils.getSubject().logout() before returning the response. This has
> the effect of setting the principalsCollection to null, so all subsequent
> permission lookups fail for the Subject. This means that permission lookups
> performed by the background thread now fail.
>
> Does anyone have any suggestions for how to keep a subject usable in a
> background thread after logout() has been called? There seem to be several
> options:
>
> - not call logout() at the end of each API request. Would this be bad
> practice? Would there be some accumulation of Subject or Http Session
> instances over time and 000s of API requests?
> - stop using Shiro for API permissions lookups - we would prefer to use the
> same permissions mechanism for all clients, so this option is not
> attractive
> - Use reflection to set the PrincipalCollection back into the Subject after
> calling logout - this seems a bit hacky and potentially fragile
>
> Any advice or examples of using Shiro to secure APIs would be greatly
> appreciated, thanks Richard
>
>
>
> --
> Sent from: http://shiro-user.582556.n2.nabble.com/
>

Reply via email to