The previous two tutorials, JAAS Authentication and JAAS Authorization, show how you can use the LoginContext and Subject classes to write a program to
This tutorial describes a Login utility that performs the above operations and then executes any specified application as the authenticated user.
Use of the Login utility with a sample application is demonstrated in this tutorial. The next tutorial, a client/server application using the Java GSS-API, also uses the Login utility.
It is not necessary to read the previous two tutorials on JAAS authentication and authorization prior to reading this one. However, you may want to refer to some sections in those tutorials to obtain further details regarding certain topics, such as how to make user-based policy file statements. You should also read JAAS Login Configuration File for information as to what a login configuration file is, since one is needed for this and all other tutorials in this series.
As with all tutorials in this series of tutorials, the underlying technology used to support authentication is Kerberos. See Kerberos Requirements.
If you want to first see the tutorial code in action, you can
skip directly to Running the Sample Program
with the Login Utility and then go back to the other sections
to learn more.
You do not need to understand the code contained in Login.java; you can just use it as is. However, you need to understand some facts about what it does so that your program, policy file, and login configuration file will properly work with it. Below is a summary of these facts, followed by sections with further information and examples.
The Login class does the following:
com.sun.security.auth.callback
package) as the class
to be used when communicating with the user. This class can prompt
the user for a user name and password.Login.java
), passing it the application arguments, if
any.Subject.doAsPrivileged
, passing it a
Subject representing the user, the MyAction instance, and a null
AccessControlContext. The result is that the public static main
method from your application is invoked and your application code
is considered to be executed on behalf of the user.To utilize the Login utility to authenticate the user and execute your application, you may need a small number of additions or modifications to your login configuration file and policy file, as described in the following.
In order to utilize the Login utility, your application code
does not need anything special. All you need is for the entry point
of your application to be the main
method of a class
you write, as usual.
The way to invoke Login such that it will authenticate the user and then instantiate MyAction to invoke your application is the following:
java <options> Login <AppName> <app arguments>where <AppName> is your application's top-level class name and <app arguments> are any arguments required by your application. See Running the Sample Program with the Login Utility for the full command used for this tutorial.
Whenever a LoginContext is used to authenticate the user, you need a login configuration file to specify the desired login module. See the The Login Configuration File section in the JAAS authentication tutorial for more information as to what a login configuration file is and what it contains.
When you use the Login utility, the name for the login configuration file entry must be exactly the same as your top-level application class name. See The Login Configuration File in this tutorial for an example.
Whenever you run an application with a security manager, you
need a policy indicating the permissions granted to specific code,
or to specific code being executed by a specific user (or users).
One way of specifying the policy is by grant
statements in a policy file. See The Policy File
for more information.
If you use the Login utility to invoke your application, then you will need to grant it various permissions, as described in Permissions Required by the Login and MyAction Classes.
SampleAction.java
application did in the previous
(JAAS Authorization) tutorial. It does
the following:
java.home
system
property,user.home
system
property, andfoo.txt
exists in the current directory.Here is the code:
import java.io.File; public class Sample { public static void main (String[] args) throws SecurityException { // If there were any arguments to read, we'd do it here. System.out.println("\nYour java.home property value is: " +System.getProperty("java.home")); System.out.println("\nYour user.home property value is: " +System.getProperty("user.home")); File f = new File("foo.txt"); System.out.print("\nfoo.txt does "); if (!f.exists()) System.out.print("not "); System.out.println("exist in the current working directory."); } }
The sample.conf login configuration
file for this tutorial contains a single entry, just like the login
configuration file for the previous (JAAS
Authorization) tutorial. The entry contents are the same since
the class implementing the desired authentication technology in
both cases is the Krb5LoginModule in the
com.sun.security.auth.module
package.
The only difference is the name used for the entry. In the previous tutorial we used the name "JaasSample", since that is the name used by the JaasAzn class to look up the entry. When you use the Login utility with your application, it expects the name for your login configuration file entry to be the same as the name of your top-level application class. That application class for this tutorial is named "Sample" so that must also be the name of the login configuration file entry. Thus the login configuration file looks like the following:
Sample { com.sun.security.auth.module.Krb5LoginModule required; };
The "required" indicates that login using the Krb5LoginModule is required to "succeed" in order for authentication to be considered successful. The Krb5LoginModule succeeds only if the name and password supplied by the user are successfully used to log the user into the Kerberos KDC.
For information about all the possible options that can be passed to Krb5LoginModule, see the Krb5LoginModule documentation.
The Login, MyAction, and Sample classes all perform some security-sensitive operations and thus relevant permissions are required in a policy file in order for the operations to be executed.
For this tutorial, you will create a Login.jar
JAR
file containing the Login.class
and
MyAction.class
files. You need to grant
Login.jar
various permissions, specifically the ones
required for invoking the security-sensitive methods the
Login.jar
classes call, as well as all the permissions
required by your application. Otherwise, access control checks will
fail.
The simplest thing to do, and what we recommend, is to grant
Login.jar AllPermission
. For this tutorial, the
Login.jar
file is assumed to be in the current
directory and the policy file includes the following:
grant codebase "file:./Login.jar" { permission java.security.AllPermission; };
(Note: This section is essentially a modified copy of the Permissions Required by SampleAction section from the previous (JAAS Authorization) tutorial, since Sample and SampleAction perform the same operations and thus require the same permissions.)
The Sample
code does three operations for which
permissions are required. It
foo.txt
exists in the current directory.The permissions required for these operations are the following:
permission java.util.PropertyPermission "java.home", "read"; permission java.util.PropertyPermission "user.home", "read"; permission java.io.FilePermission "foo.txt", "read";
We need to grant these permissions to the code in
Sample.class
, which we will place in a JAR file named
Sample.jar
. However, our grant
statement
will grant the permissions not just to the code but to a
specific authenticated user executing the code. This illustrates
how you can use a Principal designation in a grant
statement to restrict execution of security-sensitive operations in
code to a specific user rather than allowing the permissions to all
users executing the code.
Thus, as explained in How
Do You Make Principal-Based Policy File Statements?, our
grant
statement looks like the following:
grant codebase "file:./Sample.jar", Principal javax.security.auth.kerberos.KerberosPrincipal "your_user_name@your_realm" { permission java.util.PropertyPermission "java.home", "read"; permission java.util.PropertyPermission "user.home", "read"; permission java.io.FilePermission "foo.txt", "read"; };Important: You must substitute your Kerberos user name (complete with "@" and realm) for "
your_user_name@your_realm
". For example, if your
user name is "mjones" and your realm is "KRBNT-OPERATIONS.ABC.COM",
you would use "mjones@KRBNT-OPERATIONS.ABC.COM" (complete with the
quotes).
The full policy file is sample.policy.
To execute the Sample application with the Login utility, do the following:
sample.policy
with your user name and realm.Login.java
and Sample.java
:
javac Login.java Sample.java
Note that Login.java
contains two classes and thus
compiling Login.java
creates Login.class
and MyAction.class
.
Login.jar
containing
Login.class and MyAction.class
:
jar -cvf Login.jar Login.class MyAction.class
Sample.jar
containing
Sample.class
:
jar -cvf Sample.jar Sample.class
Login
class, specifying
-classpath
clause that classes
should be searched for in the Login.jar
and
Sample.jar
JAR files,-Djava.security.manager
that a security manager
should be installed,-Djava.security.krb5.realm=<your_realm>
that your Kerberos realm is the one specified.-Djava.security.krb5.kdc=<your_kdc>
that
your Kerberos KDC is the one specified.-Djava.security.policy=sample.policy
that the
policy file to be used is sample.policy
, and-Djava.security.auth.login.config=sample.conf
that the login configuration file to be used is
sample.conf
.You pass the name of your application (in this case, "Sample") as an argument to Login. You would then add as arguments any arguments required by your application, but in our case Sample does not require any.
Below are the full commands to use for both Microsoft Windows
and Solaris, Linux, and Mac OS X systems. The only difference is
that on Windows systems
you use semicolons to separate classpath items, while you use
colons for that purpose on Solaris, Linux, and Mac OS X systems.
Be sure to replace
<your_realm>
with your Kerberos realm, and
<your_kdc>
with your Kerberos KDC.
Here is the full command for Windows systems:
java -classpath Login.jar;Sample.jar -Djava.security.manager -Djava.security.krb5.realm=<your_realm> -Djava.security.krb5.kdc=<your_kdc> -Djava.security.policy=sample.policy -Djava.security.auth.login.config=sample.conf Login Sample
Here is the full command for Solaris, Linux, and Mac OS X systems:
java -classpath Login.jar:Sample.jar -Djava.security.manager -Djava.security.krb5.realm=<your_realm> -Djava.security.krb5.kdc=<your_kdc> -Djava.security.policy=sample.policy -Djava.security.auth.login.config=sample.conf Login Sample
Type the full command on one line. Multiple lines are used here for legibility. If the command is too long for your system, you may need to place it in a .bat file (for Windows) or a .sh file (for Solaris, Linux, and Mac OS X) and then run that file to execute the command.
You will be prompted for your Kerberos user name and password,
and the underlying Kerberos login module specified in the login
configuration file will log you into Kerberos. Once authentication
is successfully completed, the Sample
code will be
executed on behalf of you, the user. The sample.policy
policy file grants you the required permissions, so you will see a
display of the values of your java.home
and
user.home
system properties and a statement as to
whether or not you have a file named foo.txt
in the
current directory.
For login troubleshooting suggestions, see Troubleshooting.