[ 
https://issues.apache.org/jira/browse/SHIRO-646?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Martin Nybo Nielsen updated SHIRO-646:
--------------------------------------
    Description: 
When programatically creating a DefaultWebSecurityManager, it is not possible 
to login a DelegatingSubject, for example built through Subject.Builder.

 

Pull request: 

SHIRO-646 Allow a DelegatingSubject to login Statelessly on a 
DefaultWebSecurityManager #82

 

 

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:

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.

 

  was:
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.

 


> 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
>            Priority: Major
>              Labels: pull-request-available, test
>
> When programatically creating a DefaultWebSecurityManager, it is not possible 
> to login a DelegatingSubject, for example built through Subject.Builder.
>  
> Pull request: 
> SHIRO-646 Allow a DelegatingSubject to login Statelessly on a 
> DefaultWebSecurityManager #82
>  
>  
> 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:
> 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)

Reply via email to