You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@shiro.apache.org by Martin Nielsen <mn...@gmail.com> on 2018/04/05 07:23:07 UTC

Authenticating a Subject without a session with a WebSecurityManager

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 :)

Re: Authenticating a Subject without a session with a WebSecurityManager

Posted by Martin Nielsen <mn...@gmail.com>.
No problem. I just wanted to make sure you weren't waiting for me to do
something.

On Thu, Apr 26, 2018 at 4:24 PM, Brian Demers <br...@gmail.com>
wrote:

> Sorry for the delay, (I should have taken care of this sooner)
>
> I'll get it merged this week, unless someone else gets to it first!
>
> On Thu, Apr 26, 2018 at 5:03 AM, Martin Nielsen <mn...@gmail.com> wrote:
>
>> Hi Brian
>>
>> Are you guys satisfied with the pull request or are you still waiting for
>> something from me?
>> I just want to be sure i'm not being a bottleneck here :)
>>
>> -Martin
>>
>> On Tue, Apr 10, 2018 at 3:52 PM, Brian Demers <br...@gmail.com>
>> wrote:
>>
>>> Great!!
>>>
>>> On Tue, Apr 10, 2018 at 4:29 AM, Martin Nielsen <mn...@gmail.com>
>>> wrote:
>>>
>>>> I mailed the ICLA to  secretary@apache.org this morning
>>>>
>>>> On Mon, Apr 9, 2018 at 3:50 PM, Brian Demers <br...@gmail.com>
>>>> wrote:
>>>>
>>>>> Thanks!! I left a few minor comments and a pointer to the Apache icla:
>>>>> https://www.apache.org/licenses/icla.pdf
>>>>>
>>>>> IIRC, the use of NATIVE_SESSION_MODE and/or DefaultWebSessionManager,
>>>>> reverts to the non-web DefaultSessionManager when there is no web context.
>>>>>
>>>>> On Mon, Apr 9, 2018 at 6:17 AM, Martin Nielsen <mn...@gmail.com>
>>>>> wrote:
>>>>>
>>>>>> 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(DefaultWebSecurityM
>>>>>> anager.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 <br...@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 <mn...@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, <br...@gmail.com>
>>>>>>>> wrote:
>>>>>>>>
>>>>>>>>> Hey Martin,
>>>>>>>>>
>>>>>>>>> Take a look at the few sections following:
>>>>>>>>> https://shiro.apache.org/session-management.html#disabling-s
>>>>>>>>> ubject-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 <mn...@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 <mn...@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.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(Del
>>>>>>>>>>> egatingSubject.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 :)
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>
>>>>>>>
>>>>>>
>>>>>
>>>>
>>>
>>
>

Re: Authenticating a Subject without a session with a WebSecurityManager

Posted by Brian Demers <br...@gmail.com>.
Sorry for the delay, (I should have taken care of this sooner)

I'll get it merged this week, unless someone else gets to it first!

On Thu, Apr 26, 2018 at 5:03 AM, Martin Nielsen <mn...@gmail.com> wrote:

> Hi Brian
>
> Are you guys satisfied with the pull request or are you still waiting for
> something from me?
> I just want to be sure i'm not being a bottleneck here :)
>
> -Martin
>
> On Tue, Apr 10, 2018 at 3:52 PM, Brian Demers <br...@gmail.com>
> wrote:
>
>> Great!!
>>
>> On Tue, Apr 10, 2018 at 4:29 AM, Martin Nielsen <mn...@gmail.com> wrote:
>>
>>> I mailed the ICLA to  secretary@apache.org this morning
>>>
>>> On Mon, Apr 9, 2018 at 3:50 PM, Brian Demers <br...@gmail.com>
>>> wrote:
>>>
>>>> Thanks!! I left a few minor comments and a pointer to the Apache icla:
>>>> https://www.apache.org/licenses/icla.pdf
>>>>
>>>> IIRC, the use of NATIVE_SESSION_MODE and/or DefaultWebSessionManager,
>>>> reverts to the non-web DefaultSessionManager when there is no web context.
>>>>
>>>> On Mon, Apr 9, 2018 at 6:17 AM, Martin Nielsen <mn...@gmail.com>
>>>> wrote:
>>>>
>>>>> 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(DefaultWebSecurityM
>>>>> anager.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 <br...@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 <mn...@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, <br...@gmail.com>
>>>>>>> wrote:
>>>>>>>
>>>>>>>> Hey Martin,
>>>>>>>>
>>>>>>>> Take a look at the few sections following:
>>>>>>>> https://shiro.apache.org/session-management.html#disabling-s
>>>>>>>> ubject-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 <mn...@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 <mn...@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.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(Del
>>>>>>>>>> egatingSubject.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 :)
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>
>>>>>>
>>>>>
>>>>
>>>
>>
>

Re: Authenticating a Subject without a session with a WebSecurityManager

Posted by Martin Nielsen <mn...@gmail.com>.
Hi Brian

Are you guys satisfied with the pull request or are you still waiting for
something from me?
I just want to be sure i'm not being a bottleneck here :)

-Martin

On Tue, Apr 10, 2018 at 3:52 PM, Brian Demers <br...@gmail.com>
wrote:

> Great!!
>
> On Tue, Apr 10, 2018 at 4:29 AM, Martin Nielsen <mn...@gmail.com> wrote:
>
>> I mailed the ICLA to  secretary@apache.org this morning
>>
>> On Mon, Apr 9, 2018 at 3:50 PM, Brian Demers <br...@gmail.com>
>> wrote:
>>
>>> Thanks!! I left a few minor comments and a pointer to the Apache icla:
>>> https://www.apache.org/licenses/icla.pdf
>>>
>>> IIRC, the use of NATIVE_SESSION_MODE and/or DefaultWebSessionManager,
>>> reverts to the non-web DefaultSessionManager when there is no web context.
>>>
>>> On Mon, Apr 9, 2018 at 6:17 AM, Martin Nielsen <mn...@gmail.com> wrote:
>>>
>>>> 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(DefaultWebSecurityM
>>>> anager.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 <br...@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 <mn...@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, <br...@gmail.com>
>>>>>> wrote:
>>>>>>
>>>>>>> Hey Martin,
>>>>>>>
>>>>>>> Take a look at the few sections following:
>>>>>>> https://shiro.apache.org/session-management.html#disabling-s
>>>>>>> ubject-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 <mn...@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 <mn...@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(Del
>>>>>>>>> egatingSubject.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 :)
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>
>>>>
>>>
>>
>

Re: Authenticating a Subject without a session with a WebSecurityManager

Posted by Brian Demers <br...@gmail.com>.
Great!!

On Tue, Apr 10, 2018 at 4:29 AM, Martin Nielsen <mn...@gmail.com> wrote:

> I mailed the ICLA to  secretary@apache.org this morning
>
> On Mon, Apr 9, 2018 at 3:50 PM, Brian Demers <br...@gmail.com>
> wrote:
>
>> Thanks!! I left a few minor comments and a pointer to the Apache icla:
>> https://www.apache.org/licenses/icla.pdf
>>
>> IIRC, the use of NATIVE_SESSION_MODE and/or DefaultWebSessionManager,
>> reverts to the non-web DefaultSessionManager when there is no web context.
>>
>> On Mon, Apr 9, 2018 at 6:17 AM, Martin Nielsen <mn...@gmail.com> wrote:
>>
>>> 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(DefaultWebSecurityM
>>> anager.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 <br...@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 <mn...@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, <br...@gmail.com>
>>>>> wrote:
>>>>>
>>>>>> Hey Martin,
>>>>>>
>>>>>> Take a look at the few sections following:
>>>>>> https://shiro.apache.org/session-management.html#disabling-s
>>>>>> ubject-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 <mn...@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 <mn...@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(Del
>>>>>>>> egatingSubject.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 :)
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>
>>>>
>>>
>>
>

Re: Authenticating a Subject without a session with a WebSecurityManager

Posted by Martin Nielsen <mn...@gmail.com>.
I mailed the ICLA to  secretary@apache.org this morning

On Mon, Apr 9, 2018 at 3:50 PM, Brian Demers <br...@gmail.com> wrote:

> Thanks!! I left a few minor comments and a pointer to the Apache icla:
> https://www.apache.org/licenses/icla.pdf
>
> IIRC, the use of NATIVE_SESSION_MODE and/or DefaultWebSessionManager,
> reverts to the non-web DefaultSessionManager when there is no web context.
>
> On Mon, Apr 9, 2018 at 6:17 AM, Martin Nielsen <mn...@gmail.com> wrote:
>
>> 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(DefaultWebSecurityM
>> anager.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 <br...@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 <mn...@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, <br...@gmail.com> wrote:
>>>>
>>>>> Hey Martin,
>>>>>
>>>>> Take a look at the few sections following:
>>>>> https://shiro.apache.org/session-management.html#disabling-s
>>>>> ubject-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 <mn...@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 <mn...@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(Del
>>>>>>> egatingSubject.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 :)
>>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>
>>
>

Re: Authenticating a Subject without a session with a WebSecurityManager

Posted by Brian Demers <br...@gmail.com>.
Thanks!! I left a few minor comments and a pointer to the Apache icla:
https://www.apache.org/licenses/icla.pdf

IIRC, the use of NATIVE_SESSION_MODE and/or DefaultWebSessionManager,
reverts to the non-web DefaultSessionManager when there is no web context.

On Mon, Apr 9, 2018 at 6:17 AM, Martin Nielsen <mn...@gmail.com> wrote:

> 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 <br...@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 <mn...@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, <br...@gmail.com> wrote:
>>>
>>>> Hey Martin,
>>>>
>>>> Take a look at the few sections following:
>>>> https://shiro.apache.org/session-management.html#disabling-s
>>>> ubject-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 <mn...@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 <mn...@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(Del
>>>>>> egatingSubject.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 :)
>>>>>>
>>>>>
>>>>>
>>>>
>>
>

Re: Authenticating a Subject without a session with a WebSecurityManager

Posted by Martin Nielsen <mn...@gmail.com>.
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 <br...@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 <mn...@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, <br...@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 <mn...@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 <mn...@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 :)
>>>>>
>>>>
>>>>
>>>
>

Re: Authenticating a Subject without a session with a WebSecurityManager

Posted by Brian Demers <br...@gmail.com>.
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 <mn...@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, <br...@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 <mn...@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 <mn...@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 :)
>>>>
>>>
>>>
>>

Re: Authenticating a Subject without a session with a WebSecurityManager

Posted by Martin Nielsen <mn...@gmail.com>.
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, <br...@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 <mn...@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 <mn...@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 :)
>>>
>>
>>
>

Re: Authenticating a Subject without a session with a WebSecurityManager

Posted by Brian Demers <br...@gmail.com>.
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 <mn...@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 <mn...@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 :)
>>
>
>

Re: Authenticating a Subject without a session with a WebSecurityManager

Posted by Martin Nielsen <mn...@gmail.com>.
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 <mn...@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 :)
>