> [...] There's an old thread on this same
> subject, and a module, that you can find at
> https://sourceforge.net/projects/modauthcertific/
That's one of the prior examples I looked at in coming up with this
approach. IIRC, it depended on a rigidly defined LDAP schema.
Dictating the schema is often not an option for existing environments.
> I would suggest collecting the design decisions, and the
> interactions with authn/authz/access control in trunk
> somewhere so people can follow without too much investment.
> Include config examples/use cases.
Will do. I definitely haven't addressed documentation of any of this
yet. Is there a template or pattern for config examples and use cases?
A pointer to one or more "well-done" use cases would suffice.
> The contentious parts for these things are usually:
> How does the cert map to r->user?
I stayed with the spirit of mod_ssl here. By default r->user becomes the
certificate subject DN ( SSL_CLIENT_S_DN ). If the SSLUserName
directive is employed, use that instead. The advantage of this approach
is that it should work with almost every LDAP implementation--those
where the certificate subject is also the LDAP object's DN, and those
where a component of the subject--such as the CN--must be matched to an
attribute of the LDAP object.
As I noted in the bugzilla entry, though, I had to "tweak" mod_ssl to
return the DN in RFC2253 format. The backwards compatible thing to do
is to configure mod_ssl to optionally return the DN in RFC2253 syntax OR
add a new SSL variable that has the LDAP-formatted DN, and then use
SSLUserName to select that variable when needed. [The current behavior
in mod_ssl used to retrieve the subject or issuer DN uses a method
formally deprecated in OpenSSL--of course, it's not likely that it'll be
going away any time soon.]
Examples:
1)
# Find the user's entry in LDAP by matching a component of the
subject certificate to an attribute in LDAP
SSLUserName SSL_CLIENT_S_DN_UID
AuthLLDAPUrl
ldaps://ldap.example.com/dc=example,dc=com?uid,fullname?sub
# For AuthType Certificate, mod_authnz_ldap will do a subtree search
# from dc=example,dc=com for (&(uid=)(objectclass=*))
2)
# Find the user's entry in LDAP by the full certificate subject DN
AuthLDAPUrl ldaps://ldap.example.com/dc=example,dc=com?fullname?sub
AuthLDAPRemoteUserIsDN
# Currently, I'm overloading the semantics of AuthLDAPRemoteUserIsDN:
# when AuthType is Certificate this directive causes us to do an
# LDAP_SCOPE_BASE search for r->user, expected to be the full DN in
RFC2253
# this is guaranteed to return either 0 or 1 directory objects.
# In this scenario fullname is still retrieved and placed in the
AUTHENTICATE_FULLNAME
# environment variable; it is not used to search for the LDAP object.
Likewise the
# scope parameter of the LDAP URL is ignored for authentication.
> How does one express that basic-auth-if-no-certificate
> (AuthType foo bar, or does the cert module pre-empty basic
> auth via some other config mechanism) What if anything
> changes in authorization providers (hopefully nothing)
In effect, nothing changes in the auhorization providers. "AuthType
Certificate Basic" does exactly what you would hope, for example:
AuthType Certificate Basic
AuthName "Certificate authentication with Basic fallback"
AuthCertificateProvider ldap
AuthBasicProvider file
# Allow fallback from mod_authnz_ldap if user is not found in LDAP;
compare to AuthBasicAuthoritative
AuthCertificateAuthoritative off
I say "in effect," because to simplify implementation, I reused the
existing method. For Basic auth, there's no logical change. For
Certificate auth, I update behavior as appropriate.
> Unfortunately, doing this right in trunk probably makes it
> unbackportable. Getting it by hook or by crook in a
I have a working 2.2 implementation; I guess I'm signing up to distinct
changes per-branch, rather than a trunk commit and a 2.2 backport. I'm
hoping that's not as bad as one might think at first blush--where I've
made changes to the single authorization method in 2.2, I'd just have to
distribute those changes appropriately to each distinct Require ldap-*
directive method in the trunk.
> standalone 2.2 module might mean making it look like basic
> auth internally and would probably not be suitable for the
> base distribution.
I'm not sure what you mean; I definitely want to avoid doing anything
unsuitable. What do I need to guard against?