Feedback |
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:
- Assumes it is passed, as arguments, your application's top-level class name, followed by any arguments your application may require.
- Assumes that the class name of your top-level application class is also used as the name of the entry to be looked up in your login configuration file.
- Specifies the TextCallbackHandler class (from the 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.
- Uses a LoginContext to authenticate the user. The LoginContext invokes the appropriate authentication technology, or LoginModule, to perform the authentication. LoginModules use a CallbackHandler (in our case, TextCallbackHandler) as needed to communicate with the user.
- Allows the user three attempts to successfully log in.
- Creates an instance of the MyAction class (also in Login.java), passing it the application arguments, if any.
- Invokes 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.
Application Requirements
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:
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.java <options> Login <AppName> <app arguments>Login Configuration File Requirements
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.
Policy File Requirements
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.
The Sample.java application used for this tutorial performs the same actions as the SampleAction.java application did in the previous (JAAS Authorization) tutorial. It does the following:
- Reads and prints the value of the java.home system property,
- Reads and prints the value of the user.home system property, and
- Determines whether or not a file named foo.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.
Permissions Required by the Login and MyAction Classes
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; };Permissions Required by Sample
(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
- reads the value of the "java.home" system property.
- reads the value of the "user.home" system property.
- checks to see whether or not a file named 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:
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).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"; };The Full Policy File
The full policy file is sample.policy.
To execute the Sample application with the Login utility, do the following:
- Place the following files into a directory:
- The Login.java source file.
- The Sample.java source file.
- The sample.conf login configuration file.
- The sample.policy policy file.
- Replace "your_user_name@your_realm" in sample.policy with your user name and realm.
- Compile Login.java and Sample.java:
javac Login.java Sample.javaNote that Login.java contains two classes and thus compiling Login.java creates Login.class and MyAction.class.
- Create a JAR file named Login.jar containing Login.class and MyAction.class:
jar -cvf Login.jar Login.class MyAction.class- Create a JAR file named Sample.jar containing Sample.class:
jar -cvf Sample.jar Sample.class- Execute the Login class, specifying
- by an appropriate -classpath clause that classes should be searched for in the Login.jar and Sample.jar JAR files,
- by -Djava.security.manager that a security manager should be installed,
- by -Djava.security.krb5.realm=<your_realm> that your Kerberos realm is the one specified.
- by -Djava.security.krb5.kdc=<your_kdc> that your Kerberos KDC is the one specified.
- by -Djava.security.policy=sample.policy that the policy file to be used is sample.policy, and
- by -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 Unix systems. The only difference is that on Windows systems you use semicolons to separate classpath items, while you use colons for that purpose on Unix 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 SampleHere is the full command for UNIX 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 SampleType 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 UNIX) 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.
Feedback |