Solving the Authentication Handler Credential Validation Problem
Created: 27. September 2013
JIRA: Implement solution to the Authentication Handler Credential Validation Problem, AbstractSlingRepository#login violates JCR spec
There does not currently exist a good and transparent way for an Authentication Handler to signal to the
ResourceResovlerFactory, that the identity of a user has been established and validated and that no further checks are required. For example an SSO authentication handler will get the identity of a user provided by the SSO handler or an OAuth 2 authentication handler proves the identity of the user by with the help of the OAuth 2 provider.
A new predefined property of the
AuthenticationInfo map is defined which can be set by the authentication handler to indicate that the user's identity has been verified and can be guaranteed:
ResourceProviderFactory services creating
ResourceProvider instances by establishing connections to the actual data store will leverage this flag to implement a pre-authentication style of access.
Implementations will just set the
ResourceResolverFactory.IDENTIFIED property in the Authentication Info map to the name of the authentication handler indicating the identity has been validated.
This replaces mechanisms used today such has implementing a LoginModule service validating a custom
JCR Resource Provider
The JCR Resource Provider will check for the property and create a
Subject used for establishing the session's owner:
Considerations for creating the
- Should the full
Subjectbe created ? That is a subject which contains the user's
Principalas well as the full set of
Principalinstances representing the set of groups of which the user is a member.
- Should only a simple
Subjectbe created as in the example above ? That is only the user's
Principalis contained and the repository implementation must then complete the set of
Principalsby the principals for the groups.
- Should a dummy
Subjectbe created which only contains a simple
Principalinstance indicating the user's name (as opposed to the actual
Principalinstance representing the actual repository principal) ?
- Should a new session be retrieved for each such access or should a long-running session be used which needs to be occasionally refreshed ?
- Should mappings from user name to
Subjectbe cached ? And how is that cache refreshed ?
- We must guard the use of the
user.identifiedproperty somehow to prevent use of this feature by code to get access to other user's data (privilege escalation).
Preventing Privilege Escalation
As noted above we must make sure that no casual user can retrieve a
ResourceResolver adding just a
user.identified property and thus escalate his own privileges.
One approach to mitigate this problem would be to leverage the
user.identified is defined and each consumer of this mechanism must have a user mapping for this subservice to the mock user
This way, the JCR Resource Provider sketched above would add this check:
Abstract Sling Repository
The Abstract Sling Repository implementation will need to fix the "
null Credentials" problem: Due to a misunderstanding the Abstract Sling Repository assumes anonymous access to the repository if the
Credentials to the login method is
null or missing. While this has been implemented like this in Jackrabbit it is actually not foreseen by the specification. Rather missing or
null Credentials indicate access to the repository using pre-authentication where the
Subject identifies the owner of the
Session to create.
So the Abstract Sling Repository implementation of the
login(String, String) method must be fixed along these lines: