Martin Nybo Nielsen created SHIRO-646:
-----------------------------------------
Summary: Unable to login a DelegatingSubject on a
DefaultWebSecurityManager
Key: SHIRO-646
URL: https://issues.apache.org/jira/browse/SHIRO-646
Project: Shiro
Issue Type: Bug
Components: Authentication (log-in)
Affects Versions: 1.4.0-RC2
Reporter: Martin Nybo Nielsen
When programatically creating a DefaultWebSecurityManager, it is not possible
to login a DelegatingSubject, for example built through Subject.Builder.
The problem is twofold.
First, in DefaultWebSecurityManager, no SessionManager is set for the
DefaultWebSessionStorageEvaluator unless the DefaultSubjectDAO is set through
the DefaultWebSecurityManager.setSubjectDAO method. The DefaultSubjectDAO and
DefaultWebSessionStorageEvaluator set in the noargs constructor in
DefaultWebSecurityManager does not set a SessionManager for the
DefaultWebSessionStorageEvaluator. The null SessionManager means that the
DefaultWebSessionStorageEvaluator will always decide to create a Session for
the DelegatingSubject, which will fail due to it not having a a HTTP
compatible session. The error occurs in ServletContainerSessionManager here:
protected Session createSession(SessionContext sessionContext) throws
AuthorizationException {
if (!WebUtils.isHttp(sessionContext)) {
String msg = "SessionContext must be an HTTP compatible implementation.";
throw new IllegalArgumentException(msg);
}
Second, The DefaultWebSubjectFactory will ALWAYS create a WebDelegatingSubject
when logging in a Subject, no matter if the Subject was, for example a
Delegating Subject to begin with.
The order of events is a follows:
DelegatingSubject is created through Subject.Builder.
DelegatingSubject.login(AuthToken) is called.
DefaultSecurityManager.login(Subject, AuthenticationToken) is called which in
turn calls createSubject(AuthenticationToken, AuthenticationInfo, Subject).
Since we are using a DefaultWebSecurityManager, createSubjectContext() returns
a DefaultWebSubjectContext.
When DefaultWebSubjectFactory is then called on to create a new Subject, it
recieves a DefaultWebSubjectContext even though the DelegatingSubject was the
caller.
That means that a WebDelegatingSubject is created with a null ServletRequest
and ServletResponse.
That fails when again in the ServletContainerSessionManager here (The same
place as before):
protected Session createSession(SessionContext sessionContext) throws
AuthorizationException {
if (!WebUtils.isHttp(sessionContext)) {
String msg = "SessionContext must be an HTTP compatible implementation.";
throw new IllegalArgumentException(msg);
}
The fix is twofold, and i will create a Pull Request for it:
Change the noargs constructor in DefaultWebSecurityManager so the
DefaultWebSessionStorageEvaluator has a SessionManager set.
Introduce a check in DefaultWebSubjectFactory which checks if the existing
Subject was NOT a WebSubject, and call the super.createSubject(context) method
if so.
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)