Hi Brian I looked a bit further at the issue and i will create a bug report when i have the chance. The websubject created by the login method ends up having both httpservlet response and requests set to null. That seems to be a pretty straight forward error. I fixed the issue by creating a new websubject factory which creates delegatingsubjects instead of websubjects if the existing subject was itself a delegatingsubject. No second securitymanager needed, at least for now.
On Thu, 5 Apr 2018, 16:22 Brian Demers, <brian.dem...@gmail.com> wrote: > Hey Martin, > > Take a look at the few sections following: > https://shiro.apache.org/session-management.html#disabling-subject-state-session-storage > Though I agree throwing an exception in this case probably isn't the best > default. > > I had a similar problem a while back and IIRC I solved it by configuring a > second SecurityManager (one configured for web access and the second for > non-web). I had a few other differences configured as well, but this > approach means you need to manage the lifecycle of the second instance. > > If that first link doesn't get you what you need, think about the second > option. But either way please create a JIRA! > > > On Thu, Apr 5, 2018 at 5:49 AM, Martin Nielsen <mny...@gmail.com> wrote: > >> Right. So i got a little further, and discovered that the problem is the >> SessionStorageEvaluator on the DefaultSubjectDAO. It is set to >> a DefaultWebSessionStorageEvaluator, seems like it should handle the >> problem with this code: >> >> //SHIRO-350: non-web subject instances can't be saved to web-only session >> managers: >> //since 1.2.1: >> if (!(subject instanceof WebSubject) && (this.sessionManager != >> null && !(this.sessionManager instanceof NativeSessionManager))) { >> return false; >> } >> >> The problem is that when i login, the DelegatingSubject i create is >> automatically changed to a WebDelegatingSubject, which means that this code >> is skipped. >> >> What happens is this: >> >> shiroSubject = subjectBuilder.buildSubject(); >> Builds a DelegatingSubject, which passes through the Evaluator without >> issue. >> >> shiroSubject.login(new UsernamePasswordToken(user, password)); >> Seems to have some unfriendly behavior as the DefaultWebSecurityManager >> delegates its login to DefaultSecurityManager, which creates a new Subject >> in its login method which becomes a WebDelegatingSubject thanks to >> the DefaultWebSubjectFactory set by the DefaultWebSecurityManager, >> which also overrides createSubjectContext() to return >> a DefaultWebSubjectContext. >> >> In short: It seems no matter what i do, a WebDelegatingSubject is ALWAYS >> created when i call the login method, causing the >> DefaultWebSessionStorageEvaluator >> to attempt to create a session for a WebDelegatingSubject which does >> not have a session as it was created from a normal DelegatingSubject. >> >> This does seem more a bug than by design, and if people shout "bug" i >> will gladly create a decent bug-report. But for now: How on earth do i get >> around this? >> >> >> On Thu, Apr 5, 2018 at 9:23 AM, Martin Nielsen <mny...@gmail.com> wrote: >> >>> Hi all >>> >>> I have an application which uses a WebSecurityManager in conjunction >>> with Apache Wicket. That works all well and good, but now I have >>> encountered a single issue where i need to authenticate a user through a >>> different entrance, which does not have any notion of http sessions. When i >>> try to login a Subject without a session like this: >>> >>> Subject shiroSubject = null; >>> Subject.Builder subjectBuilder = new >>> Subject.Builder(manager).sessionCreationEnabled(false); >>> shiroSubject = subjectBuilder.buildSubject(); >>> ... >>> shiroSubject.login(new UsernamePasswordToken(user, password)); >>> >>> I tried every permutation of sessionCreationEnabled >>> >>> >>> I get the following exception: >>> >>> >>> javax.security.auth.login.LoginException: >>> java.lang.IllegalArgumentException: SessionContext must be an HTTP >>> compatible implementation. >>> at >>> org.apache.shiro.web.session.mgt.ServletContainerSessionManager.createSession(ServletContainerSessionManager.java:103) >>> at >>> org.apache.shiro.web.session.mgt.ServletContainerSessionManager.start(ServletContainerSessionManager.java:64) >>> at >>> org.apache.shiro.mgt.SessionsSecurityManager.start(SessionsSecurityManager.java:152) >>> at >>> org.apache.shiro.subject.support.DelegatingSubject.getSession(DelegatingSubject.java:336) >>> at >>> org.apache.shiro.subject.support.DelegatingSubject.getSession(DelegatingSubject.java:312) >>> at >>> org.apache.shiro.mgt.DefaultSubjectDAO.mergePrincipals(DefaultSubjectDAO.java:204) >>> at >>> org.apache.shiro.mgt.DefaultSubjectDAO.saveToSession(DefaultSubjectDAO.java:166) >>> at >>> org.apache.shiro.mgt.DefaultSubjectDAO.save(DefaultSubjectDAO.java:147) >>> at >>> org.apache.shiro.mgt.DefaultSecurityManager.save(DefaultSecurityManager.java:383) >>> at >>> org.apache.shiro.mgt.DefaultSecurityManager.createSubject(DefaultSecurityManager.java:350) >>> at >>> org.apache.shiro.mgt.DefaultSecurityManager.createSubject(DefaultSecurityManager.java:183) >>> at >>> org.apache.shiro.mgt.DefaultSecurityManager.login(DefaultSecurityManager.java:283) >>> at >>> org.apache.shiro.subject.support.DelegatingSubject.login(DelegatingSubject.java:256) >>> >>> I then looked at WebSubject.Builder i can't create a builder without a >>> Request and Response. >>> >>> >>> So the question is: When you are using a WebSecurityManager, how do you >>> authenticate a Subject in a case where there is no Request/Response >>> available? >>> >>> The only way that I can see is to highjack the WebSecurityManager's >>> Authenticator and Authorizer and call their methods directly, completely >>> ignoring the Subject, but that feels so wrong that I am guessing that i am >>> way off :) >>> >> >> >