Separating authentication from ResourceResolver access (ammending Add ResourceResolverFactory Service Interface) (NOT IMPLEMENTED) |
Status: NOT IMPLEMENTED
Created: 14. March 2010
Author: fmeschbe
JIRA: –
References: Merging Sling API and Commons Auth API
Update: fmeschbe/27. September 2013
This concept is not being implemented because in the meantime ResourceProviderFactory
services have been introduced which can be flagged as being mandatory and thus validate credentials from authentication handlers. One such implementation is the JCR Resource Provider which does exactly that and internally validates the credentials by create a JCR Session.
With the recent introduction of the Commons Auth Bundle and the current approach to break apart the dependency on JCR API from the Commons Auth Bundle we are faced with an issue of how to authenticate an HTTP request user while at the same time not binding the authentication mechanism to any data repository.
In other words we have the following requirements:
Currently the Commons Auth bundle controls the complete process of extracting authentication information, asserting the identity and connecting to the repository:
AuthenticationHandler
servicesJcrResourceResolverFactory
to create a ResourceResolver
on top of the JCR Session.The problem here is, that the Commons Auth bundle is tied into using the JCR Repository to assert identities and into the JcrResourceResolverFactory
to connect to the data repository.
These dependencies are not entirely optimal. So a first improvement might be for the Commons Auth bundle to validate any authentication and pass the validated authentication info on the ot Commons Auth client which then uses this data to create the connection:
AuthenticationHandler
servicesResourceResolverFactory
to connect to the repository and return a ResourceResolver
The drawback here is, that (a) Commons Auth is stilled tied into the JCR API and (b) JCR Sessions are created twice thus creating quite a considerable overhead.
A new service API is defined supporting the validation of credentials:
public interface CredentialValidator { /** * Validates the credentials and returns an AuthenticationInfo * object representing the validated credentials. * The implementation may return a new object or the same as * passed as a parameter. If a new object is returned the * implementation may copy some or all properties from the * passed in object. * The passed in AuthenticationInfo object should be considered * immutable by the implementation. * @param credentials The AuthenticationInfo representing the * credentials provided by the user in the HTTP request. * @return An AuthenticationInfo object representing the * validated credentials. * @throws LoginException if the passed credentials cannot * be validated. * @throws NullPointerException if credentials is null */ public AuthenticationInfo validate(AuthenticationInfo credentials) throws LoginException; } |
The SlingAuthenticator
class makes use of the CredentialValidator
service to validate the credentials extracted by AuthenticationHandler
services. The returned AuthenticationInfo is then set as a request attribute.
The CredentialValidator
interface is implemented and registered as a service by the JCR based ResourceResolverFactory
implementation. The implementation of the method uses the credentials to authenticate with the JCR repository and returns an AuthenticationInfo object copied from the original object without the password but containing the JCR Session.
The SlingMainServlet
gets the AuthenticationInfo
object from the request attribute and passes it (as a Map
) to the ResourceResolverFactory.getResourceResolver(Map)
method to get the ResourceResolver
for the request.
The JCR based ResourceResolverFactory.getResourceResolver(Map)
knows about the CredentialValidator
implementation and can make use of the Session
object in the map to reuse the existing session.
Requests are authenticated as follows:
HttpContext.handleSecurity
handleSecurity
method calls SlingAuthenticator.handleSecurity
AuthenticationInfo
by calling AuthenticationHandler.extractCredentials
AuthenticationInfo
to CredentialValidator.validate
AuthenticationInfo
and calls Repository.login
Session
as another property and returnsAuthenticationInfo
as request attribute and sets remaining required request attributes and returnshandleSecurity
returns successfullySlingMainServlet
AuthenticationInfo
from request attribute and calls ResourceResolverFactory.getResourceResolver
with this AuthenticationInfo
(which actually extends Map
)The JCR based CredentialValidator
implementation creates a session, which may or may not be used and closed by users of the Sling Commons Auth AuthenticationSupport
service. A mechanism must be implemented to ensure Sessions placed into the AuthenticationInfo
by CredentialValidator
implementations are not left open and thus needlessly consume system resources.