Issue Details (XML | Word | Printable)

Key: SESPRINGPYTHONPY-81
Type: Bug Bug
Status: Closed Closed
Resolution: Fixed
Priority: Major Major
Assignee: Greg Turnquist
Reporter: Greg Turnquist
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
SX Spring Python

Fix AccessDecisionManager based on CherryPy 3 upgrade

Created: 13/Nov/08 06:02 PM   Updated: 01/Dec/08 01:13 PM
Component/s: Security
Affects Version/s: None
Fix Version/s: 0.9

Time Tracking:
Not Specified


 Description  « Hide
In order to upgrade to CherryPy 3, had to disable access control. Sylvain has a patch, and this is the ticket to track that on.

 All   Comments   Work Log   Change History      Sort Order: Ascending order - Click to sort in descending order
Greg Turnquist added a comment - 14/Nov/08 07:35 AM
Sylvain,

I finally found time last night to apply your patch and check things out. It nicely
handled Spring Wiki!

However, when I tried to run the unit test suite, one test failed. Also, when I
changed to your new CP3 classes in PetClinic, it also didn't work as expected.
Trying to compare differences between both of these projects, I tracked it down
to a line of code in your Spring Wiki loginForm that didn't exist in PetClinic's
loginForm. Your update to Spring Wiki has it explicitly calling on the httpContextFilter
to save its context. I don't have that line in PetClinic. By adding that line,
it worked.

However, I thought back over that, and realized that is not how I wanted the filter
to work. In both apps, there is a previous line that looks like:
SecurityContextHolder.getContext().authentication = self.authenticationManager.authenticate(token)

This is where the newly authenticated credentials are stored in the SecurityContextHolder.
And in the past, this is all it took. The purpose of HttpSessionContextIntegration
filter is to pull credentials out of the HttpSession, and store them in SecurityContextHolder
before a web request. Then, after a web request, write anything stored in SecurityContextHolder
back out to the HttpSession. I don't want my web apps directly dependent on
this filter and have to worry about interacting with it, so I need to go in and
tweak the changes you made to HttpSessionContextIntegrationFilter.

I don't think it should be difficult, I just didn't have time last night
to work on that detail. I am also probably going to replace my version of CherryPySessionStrategy,
etc. with your CP3SessionStrategy definitions. I don't really need the old classes
anyway.

Thanks,
Greg


Greg Turnquist added a comment - 16/Nov/08 07:58 PM
Sylvain,

I hate to say this, but trying to bend this patch to my needs is getter harder.
I tried to backup to the baseline, and add your features one-by-one. However, I
couldn't figure out why HttpSessionContextIntegrationFilter couldn't see
SecurityContext's new data I had stored when the user was authenticated (without
your httpContext.saveContext call). I didn't like having to make that call,
because it required my web app to directly know about the filters.

I put in some debug statements inside HttpSessionContextIntegrationFilter to log
right after the doNextFilter call, which I refer to as the back-side.

My console shows me this:

2008-11-16 20:05:07,528 - springpython.security.web.HttpSessionContextIntegrationFilter
- DEBUG - HttpSession returned null object for SPRINGPYTHON_SECURITY_CONTEXT_KEY
- new SecurityContext instance associated with SecurityContextHolder
2008-11-16 20:05:07,529 - springpython.security.web.HttpSessionContextIntegrationFilter
- DEBUG - Setting contextWhenChainProceeded to [UsernamePasswordAuthenticationToken]
User: [None] Password: [PROTECTED] GrantedAuthorities: [] Authenticated: False
2008-11-16 20:05:07,529 - springpython.security.web.HttpSessionContextIntegrationFilter
- DEBUG - Back-side of HttpSessionContextIntegrationFilter => None
2008-11-16 20:05:07,529 - springpython.security.web.HttpSessionContextIntegrationFilter
- DEBUG - [UsernamePasswordAuthenticationToken] User: [None] Password: [PROTECTED]
GrantedAuthorities: [] Authenticated: False
2008-11-16 20:05:07,529 - springpython.security.web.HttpSessionContextIntegrationFilter
- DEBUG - SecurityContextHolder cleared out, as request processing completed
2008-11-16 20:05:07,529 - springpython.security.web.FilterChainProxy - DEBUG - Returning
from the filter chain...
2008-11-16 20:05:07,530 - springpython.petclinic.view.CherryPyAuthenticationForm
- DEBUG - Trying to authenticate vet1 using the authentication manager
2008-11-16 20:05:07,530 - springpython.petclinic.view.CherryPyAuthenticationForm
- DEBUG - Storing credentials in SecurityContextHolder!
2008-11-16 20:05:07,547 - springpython.security.userdetails.DatabaseUserDetailsService
- DEBUG - Just fetched Username: vet1 Password: [PROTECTED] Authorities: ['HOLDER']
Enabled: 1 from the database
2008-11-16 20:05:07,548 - springpython.petclinic.view.CherryPyAuthenticationForm
- DEBUG - => [UsernamePasswordAuthenticationToken] User: [vet1] Password:
[PROTECTED] GrantedAuthorities: ['VET_ANY'] Authenticated: True
127.0.0.1 - - [16/Nov/2008:20:05:07] "POST /login/ HTTP/1.1" 303 90 "http://127.0.0.1:8080/login/"
"Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.3) Gecko/2008092510 Ubuntu/8.04
(hardy) Firefox/3.0.3"

In this case, HttpSessionContextIntegrationFilter completes its task and exists
BEFORE actually calling the CherryPy app. Its purpose was to have called the login
form, the login form would have saved the credentials into SecurityContextHolder,
and then on the backside of the filter, it would write the contents out to the http
session, and then it could clear out the credentials. However, this is clearly NOT
what is happening.

In this case, it appears you have successfully tied in the chain of filters, but
only in a BEFORE-advising capacity. It doesn't appear to behave "around",
which is how the filters are designed to work. I guess that is the reason you had
to tie in directly to the httpContext filter to make it work.

I have tried reading documentation on how to stick the cherrypy app at the tail
end of the wsgi stack, but I can't seem to get a clear answer. They talk about
having other tools in the chain, but I don't see how with the new APIs. I believe
FilterChainProxy had an attribute called self.application, which was meant to hold
that, so it could be stuck on the tail end of the filter chain. And then, you effectively
mount filterChainProxy as the wsgi app, and run everything from there.

I don't know what to do. I could make it work if I put a direct hook like you
did, but I'm not sure I like that architecture. I need to think about this.

Greg

Greg Turnquist added a comment - 01/Dec/08 01:13 PM
Taking Sylvain's patch, I was able to make modifications to PetClinic to get it working. Basically, I needed to merge the authentication app into the main cherrypy app. I verified stand alone and distributed were working. Changes were merged up to trunk and committed. Notice concerning lack of support has been removed from the app.