[b]Implementation[/b]
As promised, here's my solution. I subclassed ADAuthenticationModule like so:
[code]public class ADSingleSignOnAuthenticationModule extends
ADAuthenticationModule {
@Override
protected void validateUser(final String jndiConfigFilePath, final String
connectionName) throws AuthenticationException, NamingException,
LoginException, AccountException {
// Force ssoSlave (to avoid attempt to log in to LDAP as user) and call
superclass
this.getProperties().setProperty(AttributeMap.SSO_SLAVE, "true");
super.validateUser(jndiConfigFilePath, connectionName);
// Lookup user information
SearchControls ctrl = new SearchControls();
ctrl.setSearchScope(SearchControls.SUBTREE_SCOPE);
final String filter = getUserFilter(this.name);
NamingEnumeration<SearchResult> answer =
this.getContext().search(this.getProperties().getProperty(AttributeMap.INITIAL_SEARCH_STRING),
filter, ctrl);
this.parseSearchResult(answer);
}
}[/code]
and created a separate chain in jaas.config:
[code]magnoliasso {
ADSingleSignOnAuthenticationModule requisite realm=external;
info.magnolia.jaas.sp.jcr.JCRAuthorizationModule required;
};
magnolia {
info.magnolia.jaas.sp.jcr.JCRAuthenticationModule requisite;
info.magnolia.jaas.sp.jcr.JCRAuthorizationModule required;
};
[/code]
The new JAAS chain is then referenced by a custom LoginHandler. This way I can
reuse the existing CallbackHandlers etc.
[b]Suggestions[/b]
I discovered a few things along the way that could be improved in Magnolia code
(looking at 4.4.5 codebase):
1) Provide ssoSlave alternative where only authentication is external
The current ADAuthenticationModule provides the following two modes:
[code]
ssoSlave=false:
- connect to AD with admin credentials
- load user information from AD (group memberships etc)
- authenticate user by logging in to AD with user/password
ssoSlave=true:
- connect to AD with admin credentials
[/code]
This doesn't benefit the case where you just want to authenticate separately
and then continue the standard flow for AD users. A more flexible approach
would be to refactor the LoginModules into a chain with four tasks:
[code]
Task Current JCR code Current AD
code
---- ----------------
---------------
a) authenticate user JCRAuthenticationModule
ADAuthenticationModule(ssoSlave=false)
b) load user info JCRAuthenticationModule
ADAuthenticationModule(ssoSlave=false)
c) associate user with groups and roles JCRAuthenticationModule
ADAuthenticationModule
d) setup permissions based on groups/roles JCRAuthorizationModule
[/code]
If each task was to be handled by a separate LoginModule class it would be
easier to override the desired parts with only configuration or minimal
programming needed.
2) Allow LoginHandler to say "handled"
Currently the LoginFilter's LoginHandler chain will normally run through all
LoginHandlers on every request even if there is already a user logged in. For
SingleSignOn use cases you may want to force the SSO user and only allow form
login if there is no SSO user available. This would be possible by putting the
SSO LoginHandler first in the chain and then being able to return a "handled"
status to stop executing the rest of the chain, thereby disabling form login
and other login methods.
3) Improve portability (JBoss)
As described in Magnolia docs, JAAS configuration needs to be maintained in two
different files in different formats to cater for both JBoss and other
appservers. It would be good to see a single file solution (maybe possible with
JBoss dynamic security domains)?
--
Context is everything:
http://forum.magnolia-cms.com/forum/thread.html?threadId=878e325c-2ac2-4b8f-8575-640c0c0740f3
----------------------------------------------------------------
For list details, see http://www.magnolia-cms.com/community/mailing-lists.html
Alternatively, use our forums: http://forum.magnolia-cms.com/
To unsubscribe, E-mail to: <[email protected]>
----------------------------------------------------------------