I created a jira issue SHIRO-646 <https://issues.apache.org/jira/browse/SHIRO-646> as well as a pull request https://github.com/apache/shiro/pull/82
The pull request contains a test and two fixes to make the test pass. A small note to something I didn't check up on: Calling DefaultWebSecurityManager.setSessionMode(DefaultWebSecurityManager.NATIVE_SESSION_MODE); makes the error disappear. I can't invest more time in it right now, sorry. I hope to check up on it in a few days if no one can explain it outright, but trawling though all those classes has been a lengthy, albeit interesting learning experience :) -Martin On Fri, Apr 6, 2018 at 3:29 PM, Brian Demers <[email protected]> wrote: > Cool, that sounds like something we should be able to write a simple test > for too! > > On Fri, Apr 6, 2018 at 8:50 AM, Martin Nielsen <[email protected]> wrote: > >> 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, <[email protected]> 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 <[email protected]> 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 <[email protected]> >>>> 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).sessi >>>>> onCreationEnabled(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.ServletContainerSessionMana >>>>> ger.createSession(ServletContainerSessionManager.java:103) >>>>> at org.apache.shiro.web.session.mgt.ServletContainerSessionMana >>>>> ger.start(ServletContainerSessionManager.java:64) >>>>> at org.apache.shiro.mgt.SessionsSecurityManager.start(SessionsS >>>>> ecurityManager.java:152) >>>>> at org.apache.shiro.subject.support.DelegatingSubject.getSessio >>>>> n(DelegatingSubject.java:336) >>>>> at org.apache.shiro.subject.support.DelegatingSubject.getSessio >>>>> n(DelegatingSubject.java:312) >>>>> at org.apache.shiro.mgt.DefaultSubjectDAO.mergePrincipals(Defau >>>>> ltSubjectDAO.java:204) >>>>> at org.apache.shiro.mgt.DefaultSubjectDAO.saveToSession(Default >>>>> SubjectDAO.java:166) >>>>> at org.apache.shiro.mgt.DefaultSubjectDAO.save(DefaultSubjectDA >>>>> O.java:147) >>>>> at org.apache.shiro.mgt.DefaultSecurityManager.save(DefaultSecu >>>>> rityManager.java:383) >>>>> at org.apache.shiro.mgt.DefaultSecurityManager.createSubject(De >>>>> faultSecurityManager.java:350) >>>>> at org.apache.shiro.mgt.DefaultSecurityManager.createSubject(De >>>>> faultSecurityManager.java:183) >>>>> at org.apache.shiro.mgt.DefaultSecurityManager.login(DefaultSec >>>>> urityManager.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 :) >>>>> >>>> >>>> >>> >
