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 <brian.dem...@gmail.com> 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 <mny...@gmail.com> 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, <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).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 :)
>>>>>
>>>>
>>>>
>>>
>

Reply via email to