Where are your permission checks located? Can you move to check into the request instead of checking late in the batch process?
On Mon, Dec 2, 2019 at 5:57 PM Richard Adams <[email protected]> wrote: > Thanks > > On 02 December 2019 at 21:49 Brian Demers <[email protected]> wrote: > > 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. > > This just seems a good entry point to encapsulate authenticating the token > - we have an ApiTokenRealm to authenticate the token and by using this > approach we can reuse getAuthorizationInfo() method that we use for > username-password logins. Also if authentication fails we want to throw a > 401 status rather than redirect to a login page for the web UI which the > ShiroServlet filter does > > 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"? > > You are probably right, as much as anything it seems symmetrical, if we > are logging users in, to log them out again after the response is generated > > > 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? > > In the web application, the user can continue using the application while > the background job is running. When the job is finished, it notifies the > user either by email, in-app messaging or slack depending on preferences. > For API invocations, the client gets a jobId which they can use to query > for progress - we implement a thin wrapper around Spring Batch which does > the bulk of the job management. > Our application is a specialist content management system for scientific > researchers. The background job is an export task which iterates over > user's content (typically 10s to 10_000s of items) and generates HTML, PDF > or XML exports. The end result is a download link. For each candidate item > to export we do a permissions lookup to see if the user has permission to > read that item (hence the need for Shiro's permissions lookups). > From what you are saying it sounds like we can just not call logout() for > the API calls. But how to handle a user logging out of web application > while background process is running? They may have a valid reason to > logout(e.g. they are working on a shared computer and they have to leave it > unattended) but would not want their background jobs to be > stopped/cancelled. Is their some way to clone a Shiro subject and bind it > to another thread? > Thanks > Richard > > 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/ > > > >
