Reputation: 31
I have searched for days on this one, poked around in the mod_auth_kerb source and experimented a lot, to no avail, so I'm really hoping that someone can point me in the right direction on this one...
I've worked for years with Apache::AuthCookie (on apache 1.x and apache 2.x (2.2.x mostly)) and recently developed a single sign-on solution using AuthCookie (for authz only this time) and mod_auth_pubtkt for authentication against an AD back end (over LDAP). It all works great, and now I'm looking at adding Kerberos to the mix for Windows users who are logged into the AD domain before launching their web browsers. That's working (keytab generated for my single signon server, which can now validate Kerberos tickets sent to it via users' browsers and Apache) but I need to make it optional. That is, I need to set up Apache 2.2.x so that if the Kerberos header isn't there to check, there's no error or challenge created (IE, for example, prompts for credentials, which I don't want).
In my SSO CGI code, I basically want to see if $ENV{REMOTE_USER} is populated (by mod_auth_kerb) and act accordingly if it is, and if it isn't, do what I do now (ask for the user's creds in a form, authen to an LDAP server and continue that way).
I thought that this would work:
<Location /whatever>
AuthName DualExp
AuthType Kerberos
KrbAuthRealms mumble
KrbServiceName HTTP/mumble@blah
Krb5Keytab /etc/apache2/my.krb5tab
KrbMethodNegotiate on
KrbMethodK5Passwd off
KrbLocalUserMapping on
KrbAuthoritative off
require valid-user
AuthType Site::NullAuth
PerlAuthenHandler Site::NullAuth->always
</Location>
Where Site::NullAuth is a really simple mod_perl authen handler that just returns "OK" always.
With mod_auth_kerb's "KrbAuthoritative" set to "off", it looks like Site::NullAuth is getting called all the time, not just on failure (ie. no Kerberos header for mod_auth_kerb), which was the first surprise. That would be fine if the user, as set by mod_auth_kerb on success, wasn't seemingly unavailble to Site::NullAuth. Since NullAuth gets called last, I end up with no user set ever. Or at least I think that's what's happening. In NullAuth, I'm doing this to check for the user:
sub always {
my ($auth_type, $r) = @_;
my $auth_user = $r->user;
my $prev_user = "";
$prev_user = $r->prev->user if $r->prev;
$r->server->log_error("user authenticated as $auth_user and prev is $prev_user");
return OK;
}
and seeing nothing for $r->user or $r->prev->user.
Does anyone have anything else that I could try here?
Thanks,
...Steve
Upvotes: 3
Views: 2950
Reputation: 9109
There is no easy way to get this to work well with I.E. What I ended up doing was using mod_rewrite to screen out all IE clients that are from off-site and just hope that all local IE clients have tickets already. rfc 1918 addresses used to hide our real address.
# Add a rewrite rule for offsite hosts
RewriteEngine On
RewriteLog /etc/httpd/logs/ssl_rewrite_log
RewriteLogLevel 2
# IE fails hard if the user does not have a tgt for SPNEGO
# and either attempts NTLM or fails altogether depending on
# exact version. Redirect all "offsite" login attempts to
# form rather than attempt pass-thru SPNEGO login.
RewriteCond %{HTTP_USER_AGENT} ^Mozilla.*MSIE
RewriteCond %{REMOTE_ADDR} !^172\.16\..*$
RewriteRule ^/login/ /login-simple/ [PT]
Upvotes: 0
Reputation: 10361
SPNEGO interaction with browser works that way:
Generally browsers try to get Kerberos token for the user from the system and if it gets none, prompt for credentials to create one - first creates a TGT and then asks for SPN ticket to Kerberos server.
As a result, you cannot avoid browsers' credential prompt dialog box, as your code cannot get information if a browser supports Kerberos/SPNEGO authentication before triggering authentication process itself.
By the way, if SPNEGO authentication fails (user did cancel credential prompt), your code can fallback to another authentication thanks to a simple cookie tracking.
Upvotes: 1