I'm ahead of you - I already added WebUtils.bind.. calls in my implementation corresponding to ShiroFilter (that's the first issue I reported and worked around). The login issue still stands.
Kalle On Mon, Aug 24, 2009 at 11:51 AM, Les Hazlewood<[email protected]> wrote: > Ah yes, you're right - sorry about that. I'll see if I can get that > working now. It is definitely a high priority to have this working > asap. > > On Mon, Aug 24, 2009 at 2:27 PM, Kalle > Korhonen<[email protected]> wrote: >> Naturally I already did what the ShiroFilter does to get any Subject >> checks going. However Subject.login() doesn't work because of the >> reasons mentioned in my previous post (see the stacktrace - it enters >> DefaultSecurityManager.createSubject where the context is (re-)created >> and it won't have the request/response objects in it). >> >> Kalle >> >> >> On Mon, Aug 24, 2009 at 11:11 AM, Les Hazlewood<[email protected]> wrote: >>> 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 >>>>>>> >>>>>> >>>>> >>>> >>> >> >
