Java Authentication and Authorization Service (JAAS) Reference Guide
JAAS can be used for two purposes:
- for authentication of users, to reliably and securely determine who is currently executing Java code, regardless of whether the code is running as an application, an applet, a bean, or a servlet; and
- for authorization of users to ensure they have the access control rights (permissions) required to do the actions performed.
JAAS implements a Java version of the standard Pluggable Authentication Module (PAM) framework.
Traditionally Java has provided codesource-based access controls (access controls based on where the code originated from and who signed the code). It lacked, however, the ability to additionally enforce access controls based on who runs the code. JAAS provides a framework that augments the Java security architecture with such support.
JAAS authentication is performed in a pluggable fashion. This permits applications to remain independent from underlying authentication technologies. New or updated authentication technologies can be plugged under an application without requiring modifications to the application itself. Applications enable the authentication process by instantiating a LoginContext
object, which in turn references a Configuration
to determine the authentication technology or technologies, or LoginModule
(s), to be used in performing the authentication. Typical LoginModule
s may prompt for and verify a user name and password. Others may read and verify a voice or fingerprint sample.
Once the user or service executing the code has been authenticated, the JAAS authorization component works in conjunction with the core Java SE access control model to protect access to sensitive resources. Access control decisions are based both on the executing code's CodeSource
and on the user or service running the code, who is represented by a Subject
object. The Subject
is updated by a LoginModule
with relevant Principal
s and credentials if authentication succeeds.
Who Should Read This Document
This document is intended for experienced developers who require the ability to design applications constrained by a CodeSource
-based and Subject
-based security model. It is also intended to be read by LoginModule developers (developers implementing an authentication technology) prior to reading the Java Authentication and Authorization Service (JAAS): LoginModule Developer's Guide.
You may wish to first read JAAS Authentication Tutorial and JAAS Authorization Tutorial to get an overview of how to use JAAS and to see sample code in action, and then return to this document for further information.
Related Documentation
This document assumes you have already read the following:
A supplement to this guide is the JAAS LoginModule Developer's Guide, intended for experienced programmers who require the ability to write a LoginModule
implementing an authentication technology.
The following tutorials for JAAS authentication and authorization can be run by everyone:
Similar tutorials for JAAS authentication and authorization, but which demonstrate the use of a Kerberos LoginModule and thus which require a Kerberos installation, can be found at
These two tutorials are a part of Introduction to JAAS and Java GSS-API Tutorials that utilize Kerberos as the underlying technology for authentication and secure communication.
Core Classes and Interfaces
The JAAS-related core classes and interfaces can be broken into three categories: Common, Authentication, and Authorization.
Common Classes
Common classes are those shared by both the JAAS authentication and authorization components.
The key JAAS class is javax.security.auth.Subject
, which represents a grouping of related information for a single entity such as a person. It encompasses the entity's Principals, public credentials, and private credentials.
Note that the java.security.Principal
interface is used to represent a Principal. Also note that a credential, as defined by JAAS, may be any Object.
Topics
Subject
To authorize access to resources, applications first need to authenticate the source of the request. The JAAS framework defines the term subject to represent the source of a request. A subject may be any entity, such as a person or a service. Once the subject is authenticated, a javax.security.auth.Subject
is populated with associated identities, or Principals. A Subject
may have many Principal
s. For example, a person may have a name Principal
("John Doe") and a SSN Principal
("123-45-6789"), which distinguish it from other subjects.
A Subject
may also own security-related attributes, which are
referred to as credentials; see the section Credentials. Sensitive credentials that require special protection,
such as private cryptographic keys, are stored within a private credential
Set
. Credentials intended to be shared, such as public key
certificates, are stored within a public credential Set
. Different
permissions are required to access and modify the different credential
Set
s.
Subjects are created using these constructors:
public Subject();
public Subject(boolean readOnly, Set principals,
Set pubCredentials, Set privCredentials);
The first constructor creates a Subject
with empty (non-null) Set
s of Principal
s and credentials. The second constructor creates a Subject
with the specified Set
s of Principal
s and credentials. It also has a boolean argument which can be used to make the Subject
read-only. In a read-only Subject
, the Principal
and credential Set
s are immutable.
An application writer does not have to instantiate a Subject
. If the application instantiates a LoginContext
and does not pass a Subject
to the LoginContext
constructor, the LoginContext
instantiates a new empty Subject
. See the LoginContext section.
If a Subject
was not instantiated to be in a read-only state, it can be set read-only by calling the following method:
public void setReadOnly();
A javax.security.auth.AuthPermission
with target "setReadOnly" is required to invoke this method. Once in a read-only state, any attempt to add or remove Principal
s or credentials will result in an IllegalStateException
being thrown. The following method may be called to test a Subject
's read-only state:
public boolean isReadOnly();
To retrieve the Principal
s associated with a
Subject, two methods are available:
public Set getPrincipals();
public Set getPrincipals(Class c);
The first method returns all Principal
s contained in the
Subject
, while the second method only returns those
Principal
s that are an instance of the specified
Class
c
, or an instance of a subclass of Class
c
. An empty set will be returned if the Subject
does
not have any associated Principal
s.
To retrieve the public credentials associated with a Subject
, these methods are available:
public Set getPublicCredentials();
public Set getPublicCredentials(Class c);
The behavior of these methods is similar to that for the getPrincipals
methods, except in this case the public credentials are being obtained.
To access private credentials associated with a Subject
, the following methods are available:
public Set getPrivateCredentials();
public Set getPrivateCredentials(Class c);
The behavior of these methods is similar to that for the getPrincipals
and getPublicCredentials
methods.
To modify or operate upon a Subject
's Principal
Set
, public credential Set
, or private credential
Set
, callers use the methods defined in the java.util.Set
class. The following example
demonstrates this:
Subject subject;
Principal principal;
Object credential;
// ...
// add a Principal and credential to the Subject
subject.getPrincipals().add(principal);
subject.getPublicCredentials().add(credential);
Note:
AnAuthPermission
with target "modifyPrincipals",
"modifyPublicCredentials", or "modifyPrivateCredentials" is required to modify the
respective Set
s. Also note that only the sets returned via the
getPrincipals()
, getPublicCredentials()
, and
getPrivateCredentials()
methods with no arguments are backed by the
Subject
's respective internal sets. Therefore any modification to
the returned set affects the internal sets as well. The sets returned via the
getPrincipals(Class c)
, getPublicCredentials(Class
c)
, and getPrivateCredentials(Class c)
methods are not
backed by the Subject
's respective internal sets. A new set is created
and returned for each such method invocation. Modifications to these sets will not
affect the Subject
's internal sets.
In order to iterate through a Set of private credentials, you need
a javax.security.auth.PrivateCredentialPermission
to access each
credential. See the PrivateCredentialPermission
API
documentation for further information.
The following methods enable you to perform an action as a specified
Subject
:
public static <T> T callAs(Subject subject, Callable<T> action)
public static <T> T doAs(Subject subject, PrivilegedAction<T> action)
public static <T> T doAsPrivileged(Subject subject,
PrivilegedAction<T> action,
AccessControlContext acc)
Note:
The doAs and doAsPrivileged methods are deprecated for removal. Use callAs instead.If a security manager is allowed, then when you invoke
callAs
, doAs
, or doAsPrivileged
,
the Subject
may be associated with an
AccessControlContext
. The following method returns the
Subject
associated with the specified
AccessControlContext
, or null
if no
Subject
is associated with the specified
AccessControlContext
.
public static Subject getSubject(final AccessControlContext acc);
An AuthPermission
with target "getSubject" is required to
call getSubject
.
Note:
The getSubject method is deprecated for removal. Use Subject::current instead.See The doAs Methods for Performing an Action as a Particular Subject for more information.
If a security manager is not allowed, then when you perform an action with
the doAs
or callAs
method, the Subject is bound to the period of execution. The following method returns
the Subject associated with the period of execution of
the current thread or null
if no Subject has been set:
public static Subject current();
If a security manager isn't allowed, you'll get an UnsupportedOperationException if you try to obtain the
Subject
with getSubject.
See The callAs and current Methods for Performing an Action as a Particular Subject for more information.
The Subject
class also includes the following methods inherited from java.lang.Object
.
public boolean equals(Object o);
public String toString();
public int hashCode();
The callAs and current Methods for Performing an Action as a Particular Subject
Note:
The Subject::callAs and Subject:current methods replace the Subject::doAs and Subject::getSubject methods, respectively, which are deprecated for removal because they have dependencies on Security Manager APIs, which are also deprecated for removal. See JEP 411: Deprecate the Security Manager for Removal for discussion and alternatives.Call the following static method to perform an action as a particular
Subject
:
public static <T> T callAs(Subject subject, Callable<T> action)
throws CompletionException
The example SampleAzn.java
from JAAS Authorization Tutorial calls Subject::callAs as follows:
Subject.callAs(mySubject, anotherAction);
In this example, the argument anotherAction
accesses the
Subject
mySubject
with the method Subject::current
:
Callable<Void> anotherAction = () -> {
Subject s = Subject.current();
System.out.println("\nCurrent subject: " + s);
// Add a new Principal
Random r = new Random();
String pn = Integer.toString(r.nextInt());
Principal p = new sample.principal.SamplePrincipal(pn);
System.out.println("\nAdding principal " + pn);
s.getPrincipals().add(p);
// List Principals
System.out.println("\nAuthenticated user has the following Principals:");
Iterator pi = s.getPrincipals().iterator();
while (pi.hasNext()) {
Principal nextp = (Principal)pi.next();
System.out.println("\t" + nextp.toString());
}
System.out.println("\nYour java.home property: "
+ System.getProperty("java.home"));
System.out.println("\nYour user.home property: "
+ 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.");
return null;
};
If a child thread starts and terminates within the execution of its parent's
thread using structured concurrency, then the child thread can access the parent
thread's current Subject with the
Subject::current
method. The following example is from
SampleAzn.java
:
Callable<Void> addRandomPrincipal = () -> {
Subject s = Subject.current();
// Add a new Principal
Random r = new Random();
String pn = Integer.toString(r.nextInt());
Principal p = new sample.principal.SamplePrincipal(pn);
System.out.println("\nAdding principal " + pn);
s.getPrincipals().add(p);
return null;
};
Callable<Void> structuredAction = () -> {
try (var scope = new StructuredTaskScope<>()) {
scope.fork(addRandomPrincipal);
scope.fork(addRandomPrincipal);
scope.fork(addRandomPrincipal);
scope.join();
Subject s = Subject.current();
System.out.println("\nCurrent subject: " + s);
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
};
Subject.callAs(mySubject, structuredAction);
The method StructuredTaskScope::fork starts a new thread in the task
scope scope
. This method returns a
StructuredTaskScope.Subtask or a forked subtask. The example
creates three forked subtasks. Each subtask obtains the parent thread's current Subject with the Subject::current
method,
then adds a new principal to the Subject
The method
StructuredTaskScope::join waits for the subtasks in
scope
to finish before continuing. The example then prints the
Subject, which now contains three additional principals.
See Running the Authorization Tutorial Code to view the output from this example.
Note:
The classStructuredTaskScope
is part of the structured concurrency API,
which is a preview feature. A preview feature is a feature whose design, specification,
and implementation are complete, but is not permanent. A preview feature may exist in a
different form or not at all in future Java SE releases. To compile and run code that
contains preview features, you must specify additional command-line options, such as
--enable-preview -source 23
. See
Preview Language and VM Features in Java Platform, Standard Edition Java Language Updates and Structured Concurrency in Java Platform, Standard Edition Core
Libraries.
The doAs Methods for Performing an Action as a Particular Subject
Note:
The Subject::callAs and Subject:current methods replace the Subject::doAs and Subject::getSubject methods, respectively, which are deprecated for removal because they have dependencies on Security Manager APIs, which are also deprecated for removal. See JEP 411: Deprecate the Security Manager for Removal for discussion and alternatives.Also note that the Subject::doAs method behaves differently depending on whether a Security Manager is allowed or disallowed. See Deprecated Methods and Replacements in the Subject JavaDoc API documentation.
The Subject::doAsPrivileged method is also deprecated for removal because it has dependencies on Security Manager APIs. However, there is no replacement for this method.
The following static methods may be called to perform an action as a
particular Subject
:
public static Object
doAs(final Subject subject,
final java.security.PrivilegedAction action);
public static Object
doAs(final Subject subject,
final java.security.PrivilegedExceptionAction action)
throws java.security.PrivilegedActionException;
If a security manager is allowed, then both methods first associate the
specified Subject
with the current thread's
AccessControlContext
, and then execute the
PrivilegedAction
or PrivilegedExceptionAction
.
This achieves the effect of having the action run as the Subject
. The
first method can throw runtime exceptions but normal execution has it returning an
Object from the run
method of its
action
argument. The second method behaves similarly except that it
can throw a checked exception from its PrivilegedExceptionAction run
method. An AuthPermission
with target "doAs" is required to call the
doAs
methods.
If a security manager isn't allowed, then the Subject isn't associated with the current thread's
AccessControlContext
. Instead, it's bound to the period of
execution. For example, if a security manager isn't allowed, then the following example
throws an UnsupportedOperationExample when it calls
getSubject:
PrivilegedAction<Object> privAct = () -> {
AccessControlContext acc = AccessController.getContext();
// Subject::getSubject throws an UnsupportedOperationExample
// if a security manager isn't allowed
Subject s = Subject.getSubject(acc);
System.out.println("Current subject: " + s);
return null;
};
Subject.doAs(mySubject, privAct);
You can use Subject::current instead:
PrivilegedAction<Object> privAct = () -> {
Subject s = Subject.current();
System.out.println("Current subject: " + s);
return null;
};
Subject.doAs(mySubject, privAct);
However, use callAs instead doAs
. See The callAs and current Methods for Performing an Action as a Particular Subject.
Subject.doAs Example
Here is an example utilizing the first doAs
method. Assume that
someone named "Bob" has been authenticated by a LoginContext
(see the
LoginContext) and as a result a Subject
was
populated with a Principal
of class
com.ibm.security.Principal
, and that Principal
has
the name "BOB". Also assume that a SecurityManager is
allowed, and that the following exists in the access control policy (see Policy for more details on the policy file).
// grant "BOB" permission to read the file "foo.txt"
grant Principal com.ibm.security.Principal "BOB" {
permission java.io.FilePermission "foo.txt", "read";
};
Here is the sample application code:
class ExampleAction implements java.security.PrivilegedAction {
public Object run() {
java.io.File f = new java.io.File("foo.txt");
// the following call invokes a security check
if (f.exists()) {
System.out.println("File foo.txt exists");
}
return null;
}
}
public class Example1 {
public static void main(String[] args) {
// Authenticate the subject, "BOB".
// This process is described in the
// LoginContext class.
Subject bob;
// Set bob to the Subject created during the
// authentication process
// perform "ExampleAction" as "BOB"
Subject.doAs(bob, new ExampleAction());
}
}
During execution, ExampleAction
will encounter a security check
when it makes a call to f.exists()
. However, since
ExampleAction
is running as "BOB", and the policy in this example
grants the necessary FilePermission
to "BOB", the
ExampleAction
will pass the security check. If the
grant
statement in the policy is altered (adding an incorrect
CodeBase
or changing the Principal
to "MOE", for
example), then a SecurityException
will be thrown.
The doAsPrivileged Methods
The following methods also perform an action as a particular Subject
.
public static Object doAsPrivileged(
final Subject subject,
final java.security.PrivilegedAction action,
final java.security.AccessControlContext acc);
public static Object doAsPrivileged(
final Subject subject,
final java.security.PrivilegedExceptionAction action,
final java.security.AccessControlContext acc)
throws java.security.PrivilegedActionException;
An AuthPermission
with target "doAsPrivileged" is required to call the doAsPrivileged
methods.
doAs Versus doAsPrivileged
The doAsPrivileged
methods behave exactly the same as the
doAs
methods, except that instead of associating the provided
Subject
with the current thread's
AccessControlContext
, they use the provided
AccessControlContext
. In this way, actions can be restricted by
AccessControlContext
s different from the current one.
An AccessControlContext
contains information about
all the code executed since the AccessControlContext
was instantiated, including the code location and the permissions
the code is granted by the policy. In order for an access control
check to succeed, the policy must grant each code item referenced
by the AccessControlContext
the required
permissions.
If the AccessControlContext
provided to
doAsPrivileged
is null
, then the action is not
restricted by a separate AccessControlContext
. One example where this
may be useful is in a server environment. A server may authenticate multiple incoming
requests and perform a separate doAs
operation for each request. To
start each doAs
action "fresh," and without the restrictions of the
current server AccessControlContext
, the server can call
doAsPrivileged
and pass in a null
AccessControlContext
.
Principals
As mentioned previously, once a Subject is authenticated, it is populated with associated identities, or Principals. A Subject may have many Principals. For example, a person may have a name Principal ("John Doe") and an SSN Principal ("123-45-6789"), which distinguish it from other Subjects. A Principal must implement the java.security.Principal and java.io.Serializable interfaces. See Subject for information about ways to update the Principals associated with a Subject.
Credentials
In addition to associated Principals, a Subject may own security-related attributes, which are referred to as credentials. A credential may contain information used to authenticate the subject to new services. Such credentials include passwords, Kerberos tickets, and public key certificates. Credentials might also contain data that simply enables the subject to perform certain activities. Cryptographic keys, for example, represent credentials that enable the subject to sign or encrypt data. Public and private credential classes are not part of the core JAAS class library. Any class, therefore, can represent a credential.
Public and private credential classes are not part of the core JAAS class library. Developers, however, may elect to have their credential classes implement two interfaces related to credentials: Refreshable
and Destroyable
.
Topics
Refreshable
The javax.security.auth.Refreshable
interface provides the capability for a credential to refresh itself. For example, a credential with a particular time-restricted lifespan may implement this interface to allow callers to refresh the time period for which it is valid. The interface has two abstract methods:
boolean isCurrent();
This method determines whether the credential is current or valid.
void refresh() throws RefreshFailedException;
This method updates or extends the validity of the credential. The method implementation should perform an
AuthPermission("refreshCredential")
security check to ensure the caller has permission to refresh the credential.
Destroyable
The javax.security.auth.Destroyable
interface provides the capability of destroying the contents within a credential. The interface has two abstract methods:
boolean isDestroyed();
Determines whether the credential has been destroyed.
void destroy() throws DestroyFailedException;
Destroys and clears the information associated with this credential. Subsequent calls to certain methods on this credential will result in an IllegalStateException
being thrown. The method implementation should perform an AuthPermission("destroyCredential")
security check to ensure the caller has permission to destroy the credential.
Authentication Classes and Interfaces
Authentication represents the process by which the identity of a subject is verified, and must be performed in a secure fashion; otherwise a perpetrator may impersonate others to gain access to a system. Authentication typically involves the subject demonstrating some form of evidence to prove its identity. Such evidence may be information only the subject would likely know or have (such as a password or fingerprint), or it may be information only the subject could produce (such as signed data using a private key).
To authenticate a subject (user or service), the following steps are performed:
- An application instantiates a
LoginContext
. - The
LoginContext
consults aConfiguration
to load all of theLoginModule
s configured for that application. - The application invokes the
LoginContext
'slogin
method. - The
login
method invokes all of the loadedLoginModule
s. EachLoginModule
attempts to authenticate the subject. Upon success,LoginModule
s associate relevantPrincipal
s and credentials with aSubject
object that represents the subject being authenticated. - The
LoginContext
returns the authentication status to the application. - If authentication succeeded, the application retrieves the
Subject
from theLoginContext
.
The following sections describe the authentication classes.
LoginContext
The javax.security.auth.login.LoginContext
class provides the basic methods used to authenticate subjects, and provides a way to develop an application independent of the underlying authentication technology. The LoginContext
consults a Configuration
to determine the authentication services, or LoginModule
(s), configured for a particular application. Therefore, different LoginModule
s can be plugged in under an application without requiring any modifications to the application itself.
LoginContext
offers four constructors from which to choose:
public LoginContext(String name) throws LoginException;
public LoginContext(String name, Subject subject) throws LoginException;
public LoginContext(String name, CallbackHandler callbackHandler)
throws LoginException
public LoginContext(String name, Subject subject,
CallbackHandler callbackHandler) throws LoginException
All of the constructors share a common parameter: name. This argument is used by the LoginContext
as an index into the login Configuration
to determine which LoginModule
s are configured for the application instantiating the LoginContext
. Constructors that do not take a Subject as an input parameter instantiate a new Subject
. Null inputs are disallowed for all constructors. Callers require an AuthPermission
with target "createLoginContext.<name>" to instantiate a LoginContext
. Here, <name> refers to the name of the login configuration entry that the application references in the name parameter for the LoginContext
instantiation.
See CallbackHandler for information on what a CallbackHandler
is and when you may need one.
Actual authentication occurs with a call to the following method:
public void login() throws LoginException;
When login
is invoked, all of the configured LoginModule
s are invoked to perform the authentication. If the authentication succeeded, the Subject
(which may now hold Principal
s, public credentials, and private credentials) can be retrieved by using the following method:
public Subject getSubject();
To logout a Subject
and remove its authenticated Principals
and credentials, the following method is provided:
public void logout() throws LoginException;
The following code sample demonstrates the calls necessary to authenticate and logout a Subject:
// let the LoginContext instantiate a new Subject
LoginContext lc = new LoginContext("entryFoo");
try {
// authenticate the Subject
lc.login();
System.out.println("authentication successful");
// get the authenticated Subject
Subject subject = lc.getSubject();
...
// all finished -- logout
lc.logout();
} catch (LoginException le) {
System.err.println("authentication unsuccessful: " +
le.getMessage());
}
LoginModule
The LoginModule
interface gives developers the ability to implement different kinds of authentication technologies that can be plugged in under an application. For example, one type of LoginModule
may perform a user name/password-based form of authentication. Other LoginModule
s may interface to hardware devices such as smart cards or biometric devices.
Note: If you are an application writer, you do not need to understand the workings of LoginModule
s. All you have to know is how to write your application and specify configuration information (such as in a login configuration file) such that the application will be able to utilize the LoginModule specified by the configuration to authenticate the user.
If, on the other hand, you are a programmer who wishes to write a LoginModule implementing an authentication technology, see the Java Authentication and Authorization Service (JAAS): LoginModule Developer's Guide for detailed step-by-step instructions.
CallbackHandler
In some cases a LoginModule
must communicate with the user to obtain authentication information. LoginModule
s use a javax.security.auth.callback.CallbackHandler for this purpose. Applications implement the CallbackHandler
interface and pass it to the LoginContext
, which forwards it directly to the underlying LoginModule
s. A LoginModule
uses the CallbackHandler
both to gather input from users (such as a password or smart card pin number) or to supply information to users (such as status information). By allowing the application to specify the CallbackHandler
, underlying LoginModules
can remain independent of the different ways applications interact with users. For example, the implementation of a CallbackHandler
for a GUI application might display a window to solicit input from a user. On the other hand, the implementation of a CallbackHandler
for a non-GUI tool might simply prompt the user for input directly from the command line.
CallbackHandler
is an interface with one method to implement:
void handle(Callback[] callbacks)
throws java.io.IOException, UnsupportedCallbackException;
The LoginModule
passes the CallbackHandler handle
method an array of appropriate Callback
s, for example a NameCallback for the user name and a PasswordCallback for the password, and the CallbackHandler
performs the requested user interaction and sets appropriate values in the Callback
s. For example, to process a NameCallback
, the CallbackHandler
may prompt for a name, retrieve the value from the user, and call the NameCallback
's setName
method to store the name.
The CallbackHandler
documentation has a lengthy example not included in this document that readers may want to examine.
Callback
The javax.security.auth.callback
package contains the Callback interface as well as several implementations. LoginModules may pass an array of Callbacks directly to the handle method of a CallbackHandler.
Please consult the various Callback APIs for more information on their use.
Authorization Classes
To make JAAS authorization take place, granting access control permissions based not just on what code is running but also on who is running it, the following is required:
- The user must be authenticated, as described in the LoginContext section.
- The Subject that is the result of authentication must be associated with an access control context, as described in the Subject section.
- Principal-based entries must be configured in the security policy.
The following sections describe the Policy
abstract class and the
authorization-specific classes AuthPermission
and
PrivateCredentialPermission
.
Policy
The java.security.Policy
class is an abstract class for representing the system-wide access control policy. The Policy
API supports Principal
-based queries.
As a default, the JDK provides a file-based subclass implementation, which was upgraded to support Principal
-based grant
entries in policy files.
Policy files and the structure of entries within them are described in Default Policy Implementation and Policy File Syntax.
AuthPermission
The javax.security.auth.AuthPermission
class encapsulates the basic permissions required for JAAS. An AuthPermission
contains a name (also referred to as a "target name") but no actions list; you either have the named permission or you don't.
In addition to its inherited methods (from the java.security.Permission
class), an AuthPermission
has two public constructors:
public AuthPermission(String name);
public AuthPermission(String name, String actions);
The first constructor creates a new AuthPermission
with the specified name. The second constructor also creates a new AuthPermission
object with the specified name, but has an additional actions argument which is currently unused and should be null. This constructor exists solely for the Policy
object to instantiate new Permission
objects. For most other code, the first constructor is appropriate.
Currently the AuthPermission
object is used to guard access to the
Policy
, Subject
, LoginContext
,
and Configuration
objects. Refer to the AuthPermission
JavaDoc API documentation
for the list of valid names that are supported.
PrivateCredentialPermission
The javax.security.auth.PrivateCredentialPermission
class protects access to a Subject
's private credentials and provides one public constructor:
public PrivateCredentialPermission(String name, String actions);
JAAS Tutorials and Sample Programs
The JAAS Authentication and JAAS Authorization tutorials contain the following samples:
SampleAcn.java
is a sample application demonstrating JAAS authentication.SampleAzn.java
is a sample application used by the authorization tutorial. It demonstrates both authentication and authorization.- The Login Configuration File for the JAAS Authentication Tutorial describes
sample_jaas.config
, which is a sample login configuration file used by both tutorials. sampleacn.policy
is a sample policy file granting permissions required by the code for the authentication tutorial.sampleazn.policy
is a sample policy file granting permissions required by the code for the authorization tutorial.SampleLoginModule.java
is the class specified by the tutorials' login configuration file (sample_jaas.config
) as the class implementing the desired underlying authentication. SampleLoginModule's user authentication consists of simply verifying that the name and password specified by the user have specific values.SamplePrincipal.java
is a sample class implementing thePrincipal
interface. It is used by SampleLoginModule.
See the tutorials for detailed information about the applications, the policy files, and the login configuration file.
Application writers do not need to understand the code for SampleLoginModule.java
or SamplePrincipal.java
, as explained in the tutorials. Programmers who wish to write LoginModules can learn how to do so by reading the Java Authentication and Authorization Service (JAAS): LoginModule Developer's Guide.
Appendix A: JAAS Settings in the java.security Security Properties File
A number of JAAS-related settings can be configured in the java.security
master Security Properties file, which is located in the conf/security
directory of the JDK.
JAAS adds two new security properties to java.security
:
login.configuration.provider
login.config.url.n
The following pre-existing properties are also relevant for JAAS users:
policy.provider
policy.url.n
The following example demonstrates how to configure these properties. In this example,
we leave the values provided in the default java.security
file for the
policy.provider
, policy.url.n
, and login.configuration.provider
Security Properties. The default java.security
file also lists a value
for the login.config.url.n
Security
Property, but it is commented out. In the following example, it is not commented.
...
#
# Class to instantiate as the javax.security.auth.login.Configuration
# provider.
#
login.configuration.provider=sun.security.provider.ConfigFile
#
# Default login configuration file
#
#login.config.url.1=file:${user.home}/.java.login.config
#
# Class to instantiate as the system Policy. This is the name of the class
# that will be used as the Policy object. The system class loader is used to
# locate this class.
#
policy.provider=sun.security.provider.PolicyFile
# The default is to have a single system-wide policy file,
# and a policy file in the user's home directory.
#
policy.url.1=file:${java.home}/conf/security/java.policy
policy.url.2=file:${user.home}/.java.policy
...
Note:
Modifications made to this file may be overwritten by subsequent JDK updates.
However, an alternate java.security
properties file may be
specified from the command line via the system property
java.security.properties=<URL>
. This properties file appends to the system
properties file. If both properties files specify values for the same key, the value
from command-line properties file is selected, as it is the last one loaded.
Also, specifying java.security.properties==<URL>
(using two equals signs), then that
properties file will completely override the system properties file.
To disable the ability to specify an additional properties file from the
command line, set the key security.overridePropertiesFile
to
false
in the system properties file. It is set to
true
by default.
Login Configuration Provider
The default JAAS login configuration implementation provided by Oracle gets its configuration information from files and expects the information to be provided in a specific format shown in the tutorials.
The default JAAS login configuration implementation can be replaced by specifying the alternative provider class implementation in the login.configuration.provider
property.
For example:
login.configuration.provider=com.foo.Config
If the Security property login.configuration.provider
is not found, or is left unspecified, then it is set to the default value:
login.configuration.provider=com.sun.security.auth.login.ConfigFile
Note that there is no means to dynamically set the login configuration provider from the command line.
Login Configuration URLs
If you are using a login configuration implementation that
expects the configuration information to be specified in files (as
does the default implementation from Oracle), the location of the
login configuration file(s) can be statically set by specifying
their respective URLs in the login.config.url.n
property. 'n' is a consecutively numbered integer starting
with 1. If multiple configuration files are specified (if n
>= 2), they will be read and unioned into one single
configuration.
For example:
login.config.url.1=file:C:/config/.java.login.config
login.config.url.2=file:C:/users/foo/.foo.login.config
If the location of the configuration files is not set in the
java.security
properties file, and also is not
specified dynamically from the command line (via the
-Djava.security.auth.login.config
option), JAAS
attempts to load a default configuration from
file:${user.home}/.java.login.config
Policy Provider
The default policy implementation can be replaced by specifying the alternative provider class implementation in the policy.provider
property.
For example:
policy.provider=com.foo.Policy
If the Security property policy.provider
is not found, or is left unspecified, then the Policy
is set to the default value:
policy.provider=sun.security.provider.PolicyFile
Note that there is no means to dynamically set the policy provider from the command line.
Policy File URLs
The location of the access control policy files can be statically set by specifying their respective URLs in the auth.policy.url.n
property. n
is a consecutively numbered integer starting with 1. If multiple policies are specified (if n
>= 2), they will be read and unioned into one single policy.
For example:
policy.url.1=file:C:/policy/.java.policy
policy.url.2=file:C:/users/foo/.foo.policy
If the location of the policy file(s) is not set in the java.security
properties file, and is not specified dynamically from the command line (via the -Djava.security.policy
option), the access control policy defaults to the same policy as that of the system policy file installed with the JDK. That policy file
- grants all permissions to standard extensions
- allows anyone to listen on un-privileged ports
- allows any code to read certain "standard" properties that are not security-sensitive, such as the
os.name
andfile.separator
properties.
Appendix B: JAAS Login Configuration File
JAAS authentication is performed in a pluggable fashion, so Java applications can remain independent from underlying authentication technologies. Configuration information such as the desired authentication technology is specified at runtime. The source of the configuration information (for example, a file or a database) is up to the current javax.security.auth.login.Configuration implementation. The default Configuration
implementation, ConfigFile
, gets its configuration information from login configuration files. For details about the default login Configuration
implementation provided with JAAS, see the com.sun.security.auth.login.ConfigFile
class.
Login Configuration File Structure and Contents
A login configuration file consists of one or more entries, each specifying which underlying authentication technology should be used for a particular application or applications. The structure of each entry is the following:
<name used by application to refer to this entry> {
<LoginModule> <flag> <LoginModule options>;
<optional additional LoginModules, flags and options>;
};
Thus, each login configuration file entry consists of a name followed by one or more LoginModule-specific entries, where each LoginModule-specific entry is terminated by a semicolon and the entire group of LoginModule-specific entries is enclosed in braces. Each configuration file entry is terminated by a semicolon.
Example 6-1 Login Configuration File for JAAS Authentication Tutorial
As an example, the login configuration file used for the JAAS Authentication Tutorial tutorial contains just one entry, which is
Sample {
sample.module.SampleLoginModule required debug=true;
};
Here, the entry is named Sample
and that is the name that the JAAS Authentication tutorial application (SampleAcn.java
) uses to refer to this entry. The entry specifies that the LoginModule to be used to do the user authentication is the SampleLoginModule
in the sample.module
package and that this SampleLoginModule
is required to "succeed" in order for authentication to be considered successful. The SampleLoginModule
succeeds only if the name and password supplied by the user are the ones it expects (testUser
and testPassword
, respectively).
The name for an entry in a login configuration file is the name that applications use to refer to the entry when they instantiate a LoginContext, as described in JAAS Authentication Tutorial in the JAAS authentication tutorial. The name can be whatever name the application developer wishes to use. Here, the term "application" refers to whatever code does the JAAS login.
The specified LoginModules are used to control the authentication process. Authentication proceeds down the list in the exact order specified, as described in the Configuration class.
The subparts of each LoginModule-specific entry are the following:
-
LoginModule: This specifies a class implementing the desired authentication technology. Specifically, the class must be a subclass of the LoginModule class, which is in the
javax.security.auth.spi
package. A typical LoginModule may prompt for and verify a user name and password, as is done by theSampleLoginModule
(in thesample.module
package) used for these tutorials. Any vendor can provide a LoginModule implementation that you can use. Some implementations are supplied with the JDK from Oracle. You can view the reference documentation for the various LoginModules, all in thecom.sun.security.auth
package: -
flag: The flag value indicates whether success of the preceding LoginModule is
required
,requisite
,sufficient
, oroptional
. If there is just one LoginModule-specific entry, as there is in our tutorials, then the flag for it should be "required". The options are described in more detail in the Configuration class. -
LoginModule options: If the specified LoginModule implementation has options that can be set, you specify any desired option values here. This is a space-separated list of values which are passed directly to the underlying LoginModule. Options are defined by the LoginModule itself, and control the behavior within it. For example, a LoginModule may define options to support debugging/testing capabilities.
The correct way to specify options in the configuration file is by using a name-value pairing, for example
debug=true
, where the option name (in this case,debug
) and value (in this case,true
) should be separated by an equals symbol.
Example 6-2 Login Configuration File Demonstrating required, sufficient, requisite, and optional Flags
The following is a sample login configuration file that demonstrates the required
, sufficient
, requisite
, and optional
flags. See the Configuration
class for more information about these flags.
Login1 {
sample.SampleLoginModule required debug=true;
};
Login2 {
sample.SampleLoginModule required;
com.sun.security.auth.module.NTLoginModule sufficient;
com.foo.SmartCard requisite debug=true;
com.foo.Kerberos optional debug=true;
};
The application Login1 only has one configured LoginModule
, SampleLoginModule
. Therefore, an attempt by Login1 to authenticate a subject (user or service) will be successful if and only if the SampleLoginModule
succeeds.
The authentication logic for the application Login2 is easier to explain with the following table:
Table 6-1 Login2 Authentication Status
Module Class | Flag | Authentication Attempt 1 | Authentication Attempt 2 | Authentication Attempt 3 | Authentication Attempt 4 | Authentication Attempt 5 | Authentication Attempt 6 | Authentication Attempt 7 | Authentication Attempt 8 |
---|---|---|---|---|---|---|---|---|---|
|
required |
pass |
pass |
pass |
pass |
fail |
fail |
fail |
fail |
|
sufficient |
pass |
fail |
fail |
fail |
pass |
fail |
fail |
fail |
SmartCard |
requisite |
* |
pass |
pass |
fail |
* |
pass |
pass |
fail |
Kerberos |
optional |
* |
pass |
fail |
* |
* |
pass |
fail |
* |
Overall Authentication |
not applicable |
pass |
pass |
pass |
fail |
fail |
fail |
fail |
fail |
* = trivial value due to control returning to the application because a previous requisite module failed or a previous sufficient module succeeded.
Where to Specify Which Login Configuration File Should Be Used
The configuration file to be used can be specified in one of two ways:
-
On the command line.
You can use a
-Djava.security.auth.login.config
interpreter command line argument to specify the login configuration file that should be used. We use this approach for all the tutorials. For example, we run ourSampleAcn
application in the JAAS Authentication Tutorial using the following command, which specifies that the configuration file is thesample_jaas.config
file in the current directory:java -Djava.security.auth.login.config==sample_jaas.config sample.SampleAcn
Note:
If you use a single equals sign (
=
) with thejava.security.auth.login.config
system property (instead of a double equals sign (==
)), then the configurations specified by both this system property and thejava.security
file are used. -
In the Java Security Properties file.
An alternate approach to specifying the location of the login configuration file is to indicate its URL as the value of a
login.config.url.n
property in the security properties file. The Security Properties file is thejava.security
file located in theconf/security
directory of the JDK.Here,
n
indicates a consecutively-numbered integer starting with 1. Thus, if desired, you can specify more than one login configuration file by indicating one file's URL for thelogin.config.url.1
property, a second file's URL for thelogin.config.url.2
property, and so on. If more than one login configuration file is specified (that is, ifn
> 1), then the files are read and concatenated into a single configuration.Here is an example of what would need to be added to the security properties file in order to indicate the
sample_jaas.config
login configuration file used by this tutorial. This example assumes the file is in theC:\AcnTest
directory on Windows:login.config.url.1=file:C:/AcnTest/sample_jaas.config
(Note that URLs always use forward slashes, regardless of what operating system the user is running.)