This chapter describes how Kerberos Module can be applied for the user authentication over HTTP, and how the web server should be configured. On the client side we supposed to have a standard web-browser capable to handle cookies and start Java applets. The case, when a Java application is used as the web service client, is discussed in the next chapter.
To apply Kerberos authentication to the web protocol, we have to build a pretty complicated system consisted of several separated pieces. Let's define what we are going to do:
There is also one requirement, specific for Fermilab:
On the server side, we are running Tomcat server. The described Kerberos Module have been tested on ver. 4.1.27 and 5.0.28. The server-side code consists of two parts:
Security realm (in terms of Catalina servlet container) is a pluggable module
responsible for the user authentication in a certain way.
Krb5Realm
class is the realm that provides authentication of
Kerberos principals.
The class accepts user name and password as strings. The password is considered
to be an initial GSS token,
converted to a sequence of hexadecimal numbers; user name value is
disregarded. The realm restores GSS
token from the string, and tries to accept it. If this operation
succeeds, Krb5Realm
obtains an instance of the security context,
gets user name, defines a set of the user's roles from a database, and records this
login in a database log file.
In a servlet, the following calls can be used:
protected void doGet( HttpServletRequest req, HttpServletResponse rsp ) { // ... String userName = req.getRemoteUser(); // User name or null String authType = req.getAuthType(); // FORM or AUTO Boolean inRole = req.isUserInRole( "developer" ); // Role name is case sensitive! // ... }
Authentication type is FORM
if the user has been authenticated in
Krb5Realm
; and AUTO
for Auto-Authenticator.
If the user principal name belongs to the
default realm, the realm name is omitted. User names
are generally in the lower case. Each user automatically has membership in at least
two roles: public
and $<user-name>
(e.g., $apetrov
).
All other roles are defined in a database.
Auto-authenticator is used to autenticate the users on those computers that can not have Kerberos tickets at all—for example, in control rooms. Strictly speaking, this routine has no relation to Kerberos, but it works along with Kerberos Module as a part of the single system.
Auto-authenticator is implemented in
AutoAuthenticator
class. This is the Catalina's
valve that passes HTTP
requests through, checking all originating IPs. The addresses of exempt hosts
eligible for authentication without Kerberos are stored in a database along with the
corresponding user names and enabling boolean flags. If the IP in a request matches an address
from the database, and its enabling flag is true
, the system authenticates the
user automatically, setting up session ID and SSO
ID in corresponding HTTP cookies.
In order to decrease the number of database requests, all results of address
lookup (both positive and negative) are cached for about 15 minutes.
For additional security and increase of speed, AutoAuthenticator
can also use a regular expression for rough filtering of IPs before the database lookup.
Thus, in order to be authenticated without Kerberos ticket, the following conditions must be satisfied:
true;
The code providing Kerberos and auto authentication on the server side
is located in krb5realm.jar
. It should be placed in
$CATALINA_HOME/server/lib
directory along with jconn2.jar
.
Kerberos security realm should to declared in server.xml
file inside the
Host container. The keyTab
attribute specifies a name of the service
principal keytab file. The example also shows single sign-on (SSO) valve
as we use it; apparently everything will work without it, too:
<Host ... > <!-- ... --> <Valve className="org.apache.catalina.authenticator.SingleSignOn"/> <Realm className="gov.fnal.controls.tools.kerberos.realm.Krb5Realm" keyTab="/tmp/my_keytab"/> </Host>
If auto-authentication is required, it should be declared for every web-application in
a file that “extends” the global server.xml
.
This file bears the name of the corresponding web-application with
.xml
extension and should be placed in webapps
directory. The pattern
attribute specifies the regular expression used
for rough filtering of IP addresses. For example, the configuration file for
Application Index, appix.xml
, could be:
<Context path="/appix" docBase="appix" debug="0" privileged="false"> <Resources allowLinking="true"/> <Valve className="gov.fnal.controls.tools.kerberos.realm.AutoAuthenticator" pattern="^(131(\x2E)225(\x2E)d{1,3}(\x2E)\d{1,3})$"/> </Context>
In web.xml
you should specify security constraints on protected resources,
authentication type, and paths to the password and error pages.
Password form is described below. In the following example,
/login/ok.html
file is made available only for authenticated users:
<security-constraint> <display-name>Appix Security Constraint</display-name> <web-resource-collection> <web-resource-name>Application Index Protected Area</web-resource-name> <url-pattern>/login/ok.html</url-pattern> </web-resource-collection> <auth-constraint> <role-name>public</role-name> </auth-constraint> </security-constraint> <login-config> <auth-method>FORM</auth-method> <realm-name>Example Form-Based Authentication Area</realm-name> <form-login-config> <form-login-page>/login/krb5login.jsp</form-login-page> <form-error-page>/login/error.html</form-error-page> </form-login-config> </login-config>
The client in our case is a web-browser. It should support cookies, have Java plug-in ver 1.4, and be able to start Java applets.
As was mentioned earlier, on the password page we have an applet that reads the cached
Kerberos ticket, creates GSS
context, and sends the token to the server as it would be
a password. The code for the applet can be found in single krb5login.jar
,
and it is quite simple.
Java Server Page (JSP) krb5login.jsp
is used as a password form.
There are two special things about it:
krb5login.jsp
was build to resolve these issues.
Client side has been tested on variuos versions of Microsoft Internet Explorer, Netscape, Mozilla, and Safari web browsers. It works as long as corresponding Java plug-in can work. In few cases (e.g., Netscape 5 on FreeBSD) it used to crash, apparently because of a plug-in malfunction.