Aha - you've encountered something that wasn't fixed this weekend yet
- the SecurityManager.login method signature would need to change to
take in a Subject argument in addition to the AuthenticationToken.
Naturally this would be hidden from Subject API end-users, but
represents the final change for this type of state-management:

Currently the SecurityManager implementations assume that an existing
Subject is bound to the currently executing thread and can rely on the
ThreadContext.  It would then acquire the existing Subject from the
thread, and call login on that instance.  In your example, you use the
subject immediately after building it - without binding it to the
thread first.

A SecurityManager API change that accepts the Subject as a parameter
would eliminate these types of problems since it wouldn't have to
acquire the Subject from some other location anymore.  There are other
benefits too to keeping that method signature coarse-grained with the
Subject, but I digress...

In the meantime, you should be able to do what the ShiroFilter does
and ensure that a Subject is available immediately on the thread after
construction.  Then you could use SecurityUtils everywhere in your
code after that:

Subject subject = new WebSubjectBuilder(securityManager, request,
response).build();

//this API is actively changing and will undergo another change today
or tomorrow to not accept a request/response since the Subject will
already have those.
ThreadStateManager threadState = new WebThreadStateManager(subject,
request, response);
threadState.bindThreadState();

subject.login(authcToken);

If that doesn't work, feel free to reply and I'll get it straightened out.

- Les

On Mon, Aug 24, 2009 at 1:28 PM, Kalle
Korhonen<[email protected]> wrote:
> Les, thanks I really appreciate you taking time to talk through the
> changes - mostly it verifies what I was being able to deduce from the
> dffs. Yea, sounds like more tests are needed. In the meantime, can you
> comment on where this is going wrong?
>
> I'm trying to call Subject.login. Even if I change it to using the new
> builder from SecurityUtils:
>                        // 
> SecurityUtils.getSubject().login(authenticationToken);
>                        (new WebSubjectBuilder(securityManager, request,
> response).build()).login(authenticationToken);
>
> And I get a stack trace:
> Caused by: java.lang.IllegalStateException: Subject context map must
> contain a javax.servlet.ServletRequest instance to support Web Subject
> construction.
>        at 
> org.apache.shiro.web.mgt.DefaultWebSubjectFactory.getServletRequest(DefaultWebSubjectFactory.java:40)
>        at 
> org.apache.shiro.web.mgt.DefaultWebSubjectFactory.createSubject(DefaultWebSubjectFactory.java:70)
>        at 
> org.apache.shiro.mgt.DefaultSecurityManager.getSubject(DefaultSecurityManager.java:405)
>        at 
> org.apache.shiro.mgt.DefaultSecurityManager.createSubject(DefaultSecurityManager.java:275)
>        at 
> org.apache.shiro.mgt.DefaultSecurityManager.login(DefaultSecurityManager.java:372)
>        at 
> org.apache.shiro.subject.DelegatingSubject.login(DelegatingSubject.java:245)
>        at xxx.web.pages.SignIn.onValidateForm(SignIn.java:88)
>
> If you look at DefaultSecurityManager.createSubject() operations, they
> just create the context from scratch (see my previous email). So where
> is the problem - should it use the builder or should the
> DefaultWebSecurityManager override these operations or something else?
>
> Kalle
>
>
> On Mon, Aug 24, 2009 at 7:32 AM, Les Hazlewood<[email protected]> wrote:
>> Sounds like we need some test cases for this - it appears that the
>> exception you're seeing is if there is no Subject accessible to the
>> thread.  That shouldn't be the case since the ShiroFilter should have
>> bound the subject to the thread via the WebSubjectBuilder and
>> WebThreadStateManager usage.
>>
>> On Mon, Aug 24, 2009 at 1:56 AM, Kalle
>> Korhonen<[email protected]> wrote:
>>> No.. this can't be right - for example calling
>>> SecurityUtils.getSubject().login(authenticationToken) results in:
>>> java.lang.IllegalStateException: Subject context map must contain a
>>> javax.servlet.ServletRequest instance to support Web Subject
>>> construction. DefaultSecurityManager's createSubject operations create
>>> Subject context map from scratch, and obviously it won't have the
>>> required objects in the context. Les, care to clarify your refactoring
>>> plan and how this is supposed to work?
>>>
>>> Kalle
>>>
>>>
>>> On Sat, Aug 22, 2009 at 11:22 PM, Kalle
>>> Korhonen<[email protected]> wrote:
>>>> I see the internals of Shiro have been changed quite a bit in r806735.
>>>> ShiroFilter.bind() now does:
>>>>        Subject subject = new WebSubjectBuilder(getSecurityManager(),
>>>> request, response).build();
>>>>        WebThreadStateManager threadState = new
>>>> WebThreadStateManager(subject, request, response);
>>>>        threadState.bindThreadState();
>>>>
>>>> which for Tapestry integration I'm working on results in:
>>>>
>>>> java.lang.IllegalStateException: No ServletRequest found in
>>>> ThreadContext. Make sure WebUtils.bind() is being called. (typically
>>>> called by ShiroFilter)  This could also happen when running
>>>> integration tests that don't properly call WebUtils.bind().
>>>>        at 
>>>> org.apache.shiro.web.WebUtils.getRequiredServletRequest(WebUtils.java:351)
>>>>        at 
>>>> org.apache.shiro.web.session.ServletContainerSessionManager.doGetSession(ServletContainerSessionManager.java:69)
>>>>        at 
>>>> org.apache.shiro.session.mgt.AbstractSessionManager.getSession(AbstractSessionManager.java:246)
>>>>        at 
>>>> org.apache.shiro.session.mgt.AbstractSessionManager.checkValid(AbstractSessionManager.java:265)
>>>>        at 
>>>> org.apache.shiro.mgt.SessionsSecurityManager.checkValid(SessionsSecurityManager.java:294)
>>>>        at 
>>>> org.apache.shiro.mgt.DefaultSecurityManager.getSession(DefaultSecurityManager.java:196)
>>>>        at 
>>>> org.apache.shiro.mgt.DefaultSecurityManager.resolveSessionIfNecessary(DefaultSecurityManager.java:437)
>>>>        at 
>>>> org.apache.shiro.mgt.DefaultSecurityManager.getSubject(DefaultSecurityManager.java:403)
>>>>        at 
>>>> org.apache.shiro.subject.SubjectBuilder.build(SubjectBuilder.java:95)
>>>>        at 
>>>> org.trailsframework.security.services.SecurityConfiguration.service(SecurityConfiguration.java:87)
>>>>
>>>> I.e. WebSubject requires the request is already bound to thread
>>>> context, but WebThreadStateManager (that's supposed to bind it)
>>>> requires a subject to exist. If I call         WebUtils.bind(request)
>>>> before instantiating a WebSubjectBuilder, everything works. Les, is it
>>>> expected I still need to bind the request/response separately or
>>>> perhaps this is a defect/refactoring still in progress?
>>>>
>>>> Kalle
>>>>
>>>
>>
>

Reply via email to