Hi, On 21.12.2009 19:34, Justin Edelson wrote: > On Fri, Dec 18, 2009 at 2:20 AM, Felix Meschberger <fmesc...@gmail.com>wrote: > >> Hi all, >> >> Currently Sling (the SlingMainServlet) is registered with the OSGi >> HttpService using an OSGi HttpContext whose handleSecurity method is >> implemented by means of the SlingAuthenticator class. This all is >> implemented in the Sling Engine bundle. See the code [1] and the >> documentation [2] for full details. >> >> This has a number of drawbacks: >> >> * Evolution of authentication provision and implementation >> is tied to the relatively unrelated Sling core implementation >> >> * The SlingAuthenticator class can only be used by servlets >> registered with Sling itself. Servlets registered directly >> with the OSGi HttpService have to implement the >> HttpContext.handleSecurity themselves, thus causing code >> duplication >> >> * The interaction between the SlingAuthenticator logging into >> the repository (Putting the session in a request attribute) >> and the SlingMainServlet using that session and logging it >> out after request termination is somewhat asynchronous. >> >> To remedy this situation, I propose to create a new bundle with the >> authentication stuff in the Engine bundle: The o.a.s.engine.auth and >> o.a.s.engine.impl.auth packages. >> >> This allows for re-use of the authentication mechanisms by other servlets. >> >> To enable authentication support a new Service interface is defined >> which allows to implement the handleSecurity method and which allows for >> proper cleanup at the end of the request. >> >> There are some options to consider, though, and an optimal solution >> escapes my mind right now... >> >> >> Option 1: Provide clean up API in the authentication service interface >> >> The service interface is defined as: >> >> public interface AuthenticationSupport { >> public boolean handleSecurity( >> HttpServletRequest, HttpServletResponse); >> public void endRequest(HttpServletRequest); >> } >> >> The handleSecurity method is meant to implement the >> HttpService.handleSecurity method. It is speced accordingly -- also >> requiring the request attributes to be set. Additionally, the method >> must set a ResourceResolver attribute (not a JCR session) for use by the >> client. >> >> The endRequest method must be called by the client when request >> processing has terminated. The intent is for the AuthenticationSupport >> service to cleanup -- namely logout an JCR session. >> >> The drawback of this option is, that it is assymmetric: HttpContext has >> to call handleSecurity, the registered Servlet has to call endRequest. >> >> Option 2: Implement ServletRequestListener >> >> The service interface is defined as: >> >> public interface AuthenticationSupport { >> public boolean handleSecurity( >> HttpServletRequest, HttpServletResponse); >> } >> >> The handleSecurity method is meant to implement the >> HttpService.handleSecurity method. It is speced accordingly -- also >> requiring the request attributes to be set. Additionally, the method >> must set a ResourceResolver attribute (not a JCR session) for use by the >> client. >> >> In addition the SlingAuthenticator registers itself as a >> ServletRequestListener handling the requestDestroyed method to cleanup >> any setups from the handleSecurity method, namely logging out JCR >> Session(s). >> >> The drawback of this option is, that it requires support to register a >> ServletRequestListener. This is something which is not supported by the >> HttpService spec and thus may only be supported by extended >> implementation (or any future HttpService or similar spec). >> >> >> WDYT ? >> >> Regards >> Felix >> >> >> [1] https://svn.apache.org/repos/asf/sling/trunk/bundles/engine >> [2] http://sling.apache.org/site/authentication.html >> > > I'm a tad weary of introducing a dependency on a non-standard extension of > HttpService in such a critical piece of functionality. I'm curious if > there's a way to perform the authentication step *without* adding a > ResourceResolver as a request attribute (and thus eliminating the need to do > post-request cleanup) and then push the creation of the ResourceResolver > down to happen inside SlingMainServlet (or thereabouts).
That's what we already do today: we login from within the HttpContext.handleSecurity method and (currently) place the JCR Session as a request attribute -- much like the HttpService spec expects the user name, authentication type and (optionally) the UserAdmin Authorization object as request attributes. And, yes, we do this because we use the repository to verify the credentials and to prevent duplicate logins - for performance reasons. At the price of having to somehow logout the session at the end of the request. > > This may be problematic because you'd end up logging into the repository > twice for a Sling request. > > I just don't think it's reasonable to expect that if I create a Servlet and > register it with HttpService directly, that I get some special Sling > goodness automagically. Not really. If you register a servlet you have to provide an HttpContext object. If you don't provide an object, a default implementation will be used. For Sling, we provide a special HttpContext object (actually the SlingMainServlet is also the HttpContext object) implementing the handleSecurity method as described. So, servlets registered with the default context or with their own implementations do not have to do any thing. Only servlets registered with an HttpContext object whose handleSecurity method uses the new authentication service will have to behave ... But yes, I agree, that this is not nice ... Being able to inject a Servlet API 2.4 request listener would make lives easier since the authentication service could register as such and cleanup up terminated requests. (we had a thread on servlet API listeners once [1], maybe we should pick this up again and think about to build an extension for the HttpService spec to dynamically register servlet API listeners ....) Regards Felix [1] http://markmail.org/thread/cdhzd6ol7x3qg65m > > Justin >