1236 lines
68 KiB
HTML
1236 lines
68 KiB
HTML
<?xml version="1.0" encoding="UTF-8"?>
|
|
<!DOCTYPE html
|
|
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
|
<html lang="en-us" xml:lang="en-us">
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|
<meta name="security" content="public" />
|
|
<meta name="Robots" content="index,follow" />
|
|
<meta http-equiv="PICS-Label" content='(PICS-1.1 "http://www.icra.org/ratingsv02.html" l gen true r (cz 1 lz 1 nz 1 oz 1 vz 1) "http://www.rsac.org/ratingsv01.html" l gen true r (n 0 s 0 v 0 l 0) "http://www.classify.org/safesurf/" l gen true r (SS~~000 1))' />
|
|
<meta name="DC.Type" content="reference" />
|
|
<meta name="DC.Title" content="Java Authentication and Authorization Service (JAAS) 1.0" />
|
|
<meta name="abstract" content="This document was last updated March 17, 2000." />
|
|
<meta name="description" content="This document was last updated March 17, 2000." />
|
|
<meta name="DC.Relation" scheme="URI" content="jaasbase.htm" />
|
|
<meta name="DC.Relation" scheme="URI" content="jaasprep.htm" />
|
|
<meta name="DC.Relation" scheme="URI" content="jaassamp.htm" />
|
|
<meta name="copyright" content="(C) Copyright IBM Corporation 2006" />
|
|
<meta name="DC.Rights.Owner" content="(C) Copyright IBM Corporation 2006" />
|
|
<meta name="DC.Format" content="XHTML" />
|
|
<meta name="DC.Identifier" content="api" />
|
|
<meta name="DC.Language" content="en-us" />
|
|
<!-- All rights reserved. Licensed Materials Property of IBM -->
|
|
<!-- US Government Users Restricted Rights -->
|
|
<!-- Use, duplication or disclosure restricted by -->
|
|
<!-- GSA ADP Schedule Contract with IBM Corp. -->
|
|
<link rel="stylesheet" type="text/css" href="./ibmdita.css" />
|
|
<link rel="stylesheet" type="text/css" href="./ic.css" />
|
|
<title>Java Authentication and Authorization Service (JAAS)
|
|
1.0 </title>
|
|
</head>
|
|
<body id="api"><a name="api"><!-- --></a>
|
|
<!-- Java sync-link --><script language="Javascript" src="../rzahg/synch.js" type="text/javascript"></script>
|
|
<h1 class="topictitle1">Java Authentication and Authorization Service (JAAS)
|
|
1.0 </h1>
|
|
<div><p>This document was last updated March 17, 2000.</p>
|
|
<div class="section"><h4 class="sectiontitle">Developer's Guide</h4><ul><li><a href="#api__Overview"><strong>Overview</strong></a></li>
|
|
<li><a href="#api__Who"><strong>Who Should Read This Document</strong></a></li>
|
|
<li><a href="#api__RelatedDocs"><strong>Related Documentation</strong></a></li>
|
|
<li><a href="#api__Intro"><strong>Introduction</strong></a></li>
|
|
<li><a href="#api__Core"><strong>Core Classes</strong></a></li>
|
|
<li><a href="#api__Common"><strong>Common Classes</strong></a> <ul><li><a href="#api__Subject"><strong>Subject</strong></a></li>
|
|
<li><a href="#api__Principals"><strong>Principals</strong></a></li>
|
|
<li><a href="#api__Credentials"><strong>Credentials</strong></a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#api__Authentication"><strong>Authentication Classes</strong></a></li>
|
|
<li><a href="#api__LoginContext"><strong>LoginContext</strong></a></li>
|
|
<li><a href="#api__LoginModule"><strong>LoginModule</strong></a></li>
|
|
<li><a href="#api__CallbackHandler"><strong>CallbackHandler</strong></a></li>
|
|
<li><a href="#api__Callback"><strong>Callback</strong></a></li>
|
|
<li><a href="#api__Authorization"><strong>Authorization Classes</strong></a> </li>
|
|
<li><a href="#api__Policy"><strong>Policy</strong></a></li>
|
|
<li><a href="#api__AuthPermission"><strong>AuthPermission</strong></a></li>
|
|
<li><a href="#api__PrivateCredentialPermission"> <strong>PrivateCredentialPermission</strong></a></li>
|
|
</ul>
|
|
</div>
|
|
<div class="section" id="api__references"><a name="api__references"><!-- --></a><h4 class="sectiontitle">References</h4><ul><li><a href="#api__Implementation">Implementation</a></li>
|
|
<li><a href="#api__HelloWorld">"Hello World", JAAS style!</a></li>
|
|
<li><a href="#api__AppendixA">Appendix A: JAAS Settings in the java.security
|
|
Security Properties File</a></li>
|
|
<li><a href="#api__AppendixB">Appendix B: Login Configuration File</a></li>
|
|
<li><a href="#api__AppendixC">Appendix C: Authorization Policy File</a></li>
|
|
</ul>
|
|
</div>
|
|
<div class="section" id="api__Overview"><a name="api__Overview"><!-- --></a><h4 class="sectiontitle">Overview</h4><p>The Java™ Authentication
|
|
and Authorization Service (JAAS) is a standard extension to the Java 2
|
|
Software Development Kit, version 1.3. Currently, Java 2 provides codesource-based access
|
|
controls (access controls based on <em>where</em> the code originated from and <em>who
|
|
signed</em> the code). It lacks, however, the ability to additionally enforce
|
|
access controls based on <em>who runs</em> the code. JAAS provides a framework
|
|
that augments the Java 2 security model with such support.</p>
|
|
</div>
|
|
<div class="section" id="api__Who"><a name="api__Who"><!-- --></a><h4 class="sectiontitle">Who Should Read This Document</h4><p>This document
|
|
is intended for experienced programmers wanting to create applications constrained
|
|
by a codesource-based and Subject-based security model.</p>
|
|
</div>
|
|
<div class="section" id="api__RelatedDocs"><a name="api__RelatedDocs"><!-- --></a><h4 class="sectiontitle">Related Documentation</h4><p>This document
|
|
assumes you have already read the following documentation:</p>
|
|
<ul><li><a href="http://java.sun.com/reference/api/index.html" target="_blank">Java 2 Software Development Kit API Specification</a></li>
|
|
<li><a href="apidocs/index.html" target="_blank">JAAS API
|
|
Specification</a></li>
|
|
<li><a href="http://java.sun.com/security/" target="_blank">Security
|
|
and the Java platform</a></li>
|
|
</ul>
|
|
<p>A supplement to this guide is the <a href="http://java.sun.com/security/jaas/doc/module.html" target="_blank"> LoginModule Developer's Guide</a> that is supplied by
|
|
Sun Microsystems, Inc.</p>
|
|
</div>
|
|
<div class="section" id="api__Intro"><a name="api__Intro"><!-- --></a><h4 class="sectiontitle">Introduction</h4><p>The JAAS infrastructure
|
|
can be divided into two main components: an <strong>authentication</strong> component
|
|
and an <strong>authorization</strong> component. The JAAS authentication component provides
|
|
the ability to reliably and securely determine who is currently processing Java code,
|
|
regardless of whether the code is running as an application, an applet, a
|
|
bean, or a servlet. The JAAS authorization component supplements the existing Java 2
|
|
security framework by providing the means to restrict the processing Java code
|
|
from performing sensitive tasks, depending on its codesource (as is done in Java 2)
|
|
and depending on who was authenticated.</p>
|
|
<p>JAAS authentication is performed
|
|
in a <em>pluggable</em> fashion. This permits Java applications to remain independent
|
|
from underlying authentication technologies. Therefore 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</p>
|
|
<pre>LoginContext</pre>
|
|
object, which in turn references a <pre>Configuration</pre>
|
|
to determine the authentication technology, or <pre>LoginModule</pre>
|
|
, to be used in performing the authentication. Typical LoginModules
|
|
may prompt for and verify a username and password. Others may read and verify
|
|
a voice or fingerprint sample. <p>Once the user processing the code has been
|
|
authenticated, the JAAS authorization component works in conjunction with
|
|
the existing Java 2 access control model to protect access to sensitive
|
|
resources. Unlike in Java 2, where access control decisions are
|
|
based solely on code location and code signers (a</p>
|
|
<pre>CodeSource</pre>
|
|
), in JAAS access control decisions are based both on the processing
|
|
code's <pre>CodeSource</pre>
|
|
, as well as on the user running the code, or the <pre>Subject</pre>
|
|
. Note that the JAAS policy merely extends the Java 2
|
|
policy with the relevant Subject-based information. Therefore permissions
|
|
recognized and understood in Java 2 ( <pre>java.io.FilePermission</pre>
|
|
and <pre>java.net.SocketPermission</pre>
|
|
, for example) are also understood and recognized by JAAS. Furthermore,
|
|
although the JAAS security policy is physically separate from the existing Java 2
|
|
security policy, the two policies, together, form one logical policy.</div>
|
|
<div class="section" id="api__Core"><a name="api__Core"><!-- --></a><h4 class="sectiontitle">Core Classes</h4>The JAAS core classes can be
|
|
broken into 3 categories: Common, Authentication, and Authorization. <ul><li>Common Classes <ul><li>Subject, Principals, Credentials</li>
|
|
</ul>
|
|
</li>
|
|
<li>Authentication Classes <ul><li>LoginContext, LoginModule, CallbackHandler, Callback</li>
|
|
</ul>
|
|
</li>
|
|
<li>Authorization Classes <ul><li>Policy, AuthPermission, PrivateCredentialPermission</li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<div class="section" id="api__Common"><a name="api__Common"><!-- --></a><h4 class="sectiontitle">Common Classes</h4>Common classes are shared
|
|
within both the JAAS authentication and authorization components. <p>The
|
|
key JAAS class is</p>
|
|
<pre>Subject</pre>
|
|
, 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. <p>Note that JAAS uses the existing Java 2</p>
|
|
<pre>java.security.Principal</pre>
|
|
interface to represent a Principal. Also note that JAAS does
|
|
not introduce a separate credential interface or class. A credential, as defined
|
|
by JAAS, may be any Object.</div>
|
|
<div class="section" id="api__Subject"><a name="api__Subject"><!-- --></a><h4 class="sectiontitle">Subject</h4> 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 service. Once authenticated,
|
|
a Subject 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 a SSN Principal ("123-45-6789") which distinguishes it from
|
|
other Subjects. <p>A</p>
|
|
<pre>Subject</pre>
|
|
may also own security-related attributes, which are referred
|
|
to as credentials. Sensitive credentials that require special protection,
|
|
such as private cryptographic keys, are stored within a private credential
|
|
<pre>Set</pre>
|
|
. Credentials intended to be shared, such as public key certificates
|
|
or Kerberos tickets are stored within a public credential <pre>Set</pre>
|
|
. Different permissions are required to access and modify the
|
|
different credential Sets. <p>Subjects are created using these constructors:</p>
|
|
<pre> public Subject();
|
|
|
|
public Subject(boolean readOnly, Set principals,
|
|
Set pubCredentials, Set privCredentials);</pre>
|
|
The first constructor creates a Subject with empty (non-null)
|
|
Sets of Principals and credentials. The second constructor creates a Subject
|
|
with the specified Sets of Principals and credentials. It also has a boolean
|
|
argument which can create a read-only Subject (immutable Principal and credential
|
|
Sets). <p>An alternative way to obtain a reference to an authenticated Subject
|
|
without using these constructors will be shown in the <a href="#api__LoginContext">LoginContext
|
|
section.</a></p>
|
|
<p>If a Subject was not instantiated to be in a read-only
|
|
state, it can be set to a read-only state by calling this method:</p>
|
|
<pre> public void setReadOnly();</pre>
|
|
An <pre>AuthPermission("setReadOnly")</pre>
|
|
is required to invoke this method. Once in a read-only state,
|
|
any attempt to add or remove Principals or credentials will result in an
|
|
<pre>IllegalStateException</pre>
|
|
being thrown. <p>This method may be called to test a Subject's
|
|
read-only state:</p>
|
|
<pre> public boolean isReadOnly();</pre>
|
|
To retrieve the Principals associated with a Subject, two methods
|
|
are available: <pre> public Set getPrincipals();
|
|
public Set getPrincipals(Class c);</pre>
|
|
The first method returns all Principals contained in the Subject,
|
|
while the second method only returns those Principals 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 Principals.
|
|
<p>To retrieve the public credentials associated with a Subject, these methods
|
|
are available:</p>
|
|
<pre> public Set getPublicCredentials();
|
|
public Set getPublicCredentials(Class c);</pre>
|
|
The observed behavior of these methods is identical to that
|
|
for the <pre>getPrincipals</pre>
|
|
method. <p>To access private credentials associated with a
|
|
Subject, the following methods are available:</p>
|
|
<pre> public Set getPrivateCredentials();
|
|
public Set getPrivateCredentials(Class c);</pre>
|
|
The observed behavior of these methods is identical to that for
|
|
the <pre>getPrincipals</pre>
|
|
and <pre>getPublicCredentials</pre>
|
|
methods. <p>To modify or operate upon a Subject's Principal
|
|
Set, public credential Set, or private credential Set, callers use the methods
|
|
defined in the</p>
|
|
<pre>java.util.Set</pre>
|
|
class. The following example demonstrates this: <pre> Subject subject;
|
|
Principal principal;
|
|
Object credential;
|
|
|
|
// add a Principal and credential to the Subject
|
|
subject.getPrincipals().add(principal);
|
|
subject.getPublicCredentials().add(credential);</pre>
|
|
Note that an <pre>AuthPermission("modifyPrincipals")</pre>
|
|
, <pre>AuthPermission("modifyPublicCredentials")</pre>
|
|
, or <pre>AuthPermission("modifyPrivateCredentials")</pre>
|
|
is required to modify the respective Sets. Also note that only
|
|
the sets returned via the <pre>getPrincipals</pre>
|
|
, <pre>getPublicCredentials</pre>
|
|
, and <pre>getPrivateCredentials</pre>
|
|
methods 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 <pre>getPrincipals(Class c)</pre>
|
|
, <pre>getPublicCredentials(Class c)</pre>
|
|
, and <pre>getPrivateCredentials(Class c)</pre>
|
|
methods are not backed by the Subject's respective internal
|
|
sets. A new set is created and returned for each method invocation. Modifications
|
|
to these sets will not affect the Subject's internal sets. The following method
|
|
returns the Subject associated with the specified <pre>AccessControlContext</pre>
|
|
, or null if no Subject is associated with the specified <pre>AccessControlContext</pre>
|
|
. <pre> public static Subject getSubject(final AccessControlContext acc);</pre>
|
|
An <pre>AuthPermission("getSubject")</pre>
|
|
is required to call <pre>Subject.getSubject</pre>
|
|
. <p>The Subject class also includes these methods inherited
|
|
from</p>
|
|
<pre>java.lang.Object</pre>
|
|
: <pre> public boolean equals(Object o);
|
|
public String toString();
|
|
public int hashCode();</pre>
|
|
<p id="api__doas"><a name="api__doas"><!-- --></a>The following static methods may be called to perform
|
|
work as a particular Subject: </p>
|
|
<pre> 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;</pre>
|
|
Both methods first associate the specified <em><strong> subject</strong></em> with
|
|
the current Thread's <pre>AccessControlContext</pre>
|
|
, and then process the <em><strong>action</strong></em>. This achieves the
|
|
effect of having the <em><strong>action</strong></em> run as the <em><strong>subject</strong></em>.
|
|
The first method can throw runtime exceptions but normal processing 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 <pre>PrivilegedExceptionAction</pre>
|
|
run() method. An <pre>AuthPermission("doAs")</pre>
|
|
is required to call the <pre>doAs</pre>
|
|
methods. <p>Here are two examples utilizing the first</p>
|
|
<pre>doAs</pre>
|
|
method. Assume that a <pre>Subject</pre>
|
|
with a Principal of class <pre>com.ibm.security.Principal</pre>
|
|
named "BOB" has been authenticated by a <pre>LoginContext</pre>
|
|
"lc". Also, assume that a SecurityManager has been installed,
|
|
and the following exists in the JAAS access control policy (see the <a href="#api__Policy">Policy section</a> for more details on the JAAS policy
|
|
file): <pre> // Grant "BOB" permission to read the file "foo.txt"
|
|
grant Principal com.ibm.security.Principal "BOB" {
|
|
permission java.io.FilePermission "foo.txt", "read";
|
|
};</pre>
|
|
<p><strong>Subject.doAs Example 1</strong></p>
|
|
<pre> class ExampleAction implements java.security.PrivilegedAction {
|
|
public Object run() {
|
|
java.io.File f = new java.io.File("foo.txt");
|
|
|
|
// exists() 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
|
|
// <a href="#api__LoginContext">LoginContext section</a>.
|
|
|
|
Subject bob;
|
|
...
|
|
|
|
// perform "ExampleAction" as "BOB":
|
|
Subject.doAs(bob, new ExampleAction());
|
|
}
|
|
}</pre>
|
|
During processing, <pre>ExampleAction</pre>
|
|
will encounter a security check when it makes a call to, <pre>f.exists()</pre>
|
|
. However, since <pre>ExampleAction</pre>
|
|
is running as "BOB", and because the JAAS policy (above) grants
|
|
the necessary <pre>FilePermission</pre>
|
|
to "BOB", the <pre>ExampleAction</pre>
|
|
will pass the security check. <p>Example 2 has the same scenario
|
|
as Example 1.</p>
|
|
<p><strong>Subject.doAs Example 2</strong></p>
|
|
<pre> public class Example2 {
|
|
// Example of using an anonymous action class.
|
|
public static void main(String[] args) {
|
|
// Authenticate the subject, "BOB".
|
|
// This process is described in the
|
|
// <a href="#api__LoginContext">LoginContext section</a>.
|
|
|
|
Subject bob;
|
|
...
|
|
|
|
// perform "ExampleAction" as "BOB":
|
|
Subject.doAs(bob, new ExampleAction() {
|
|
public Object run() {
|
|
java.io.File f = new java.io.File("foo.txt");
|
|
if (f.exists()) {
|
|
System.out.println("File foo.txt exists.");
|
|
}
|
|
return null;
|
|
}
|
|
});
|
|
}
|
|
}</pre>
|
|
Both examples throw a <pre>SecurityException</pre>
|
|
if the example permission grant statement is altered correctly,
|
|
such as adding an incorrect CodeBase or changing the Principal to "MOE". Removing
|
|
the Principal field from the grant block and then moving it to a Java 2
|
|
policy file will not cause a <pre>SecurityException</pre>
|
|
to be thrown because the permission is more general now (available
|
|
to all Principals). <p>Since both examples perform the same function, there
|
|
must be a reason to write code one way over the other. Example 1 may be easier
|
|
to read for some programmers unfamiliar with anonymous classes. Also, the <em><strong>action</strong></em> class
|
|
could be placed in a separate file with a unique CodeBase and then the permission
|
|
grant could utilize this information. Example 2 is more compact and the <em><strong>action</strong></em> to
|
|
be performed is easier to find since it is right there in the</p>
|
|
<pre>doAs</pre>
|
|
call. <p id="api__doaspriv"><a name="api__doaspriv"><!-- --></a>The following methods also perform
|
|
work as a particular Subject. However, the</p>
|
|
<pre>doAsPrivileged</pre>
|
|
methods will have security checks based on the supplied <em><strong> action</strong></em> and <em><strong>subject</strong></em>.
|
|
The supplied context will be tied to the specified <em><strong> subject</strong></em> and <em><strong>action</strong></em>.
|
|
A null context object will disregard the current <pre>AccessControlContext</pre>
|
|
altogether. <pre> 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;</pre>
|
|
The <pre>doAsPrivileged</pre>
|
|
methods behave similarly to the <pre>doAs</pre>
|
|
methods: the <em><strong>subject</strong></em> is associated with the context <em><strong>acc</strong></em>,
|
|
an <em><strong> action</strong></em> is performed, and runtime exceptions or checked exceptions
|
|
may be thrown. However, the <pre>doAsPrivileged</pre>
|
|
methods first empties the existing Thread's <pre>AccessControlContext</pre>
|
|
before associating the <em><strong>subject</strong></em> with the supplied
|
|
context, and before invoking the <em><strong> action</strong></em>. A null <em><strong>acc</strong></em> argument
|
|
has the effect of causing access control decisions (invoked while the <em><strong>action</strong></em> processes)
|
|
to be based solely upon the <em><strong>subject</strong></em> and <em><strong> action</strong></em>.
|
|
An <pre>AuthPermission("doAsPrivileged")</pre>
|
|
is required when calling the <pre>doAsPrivileged</pre>
|
|
methods.</div>
|
|
<div class="section" id="api__Principals"><a name="api__Principals"><!-- --></a><h4 class="sectiontitle">Principals</h4>As mentioned previously,
|
|
Principals may be associated with a Subject. Principals represent Subject
|
|
identities, and must implement the <pre>java.security.Principal</pre>
|
|
and <pre>java.io.Serializable</pre>
|
|
interfaces. The <a href="#api__Subject">Subject section</a> describes
|
|
ways to update the Principals associated with a Subject.</div>
|
|
<div class="section" id="api__Credentials"><a name="api__Credentials"><!-- --></a><h4 class="sectiontitle">Credentials</h4>Public and private credential
|
|
classes are not part of the core JAAS class library. Any java class, therefore,
|
|
can represent a credential. However, developers may elect to have their credential
|
|
classes implement two interfaces related to credentials: Refreshable and Destroyable.
|
|
</div>
|
|
<div class="section" id="api__Refreshable"><a name="api__Refreshable"><!-- --></a><h4 class="sectiontitle">Refreshable</h4>This <strong>interface</strong> 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: <pre> boolean isCurrent();</pre>
|
|
Determines if the credential is current or valid. <pre> void refresh() throws RefreshFailedException;</pre>
|
|
Updates or extends the validity of the credential. This method
|
|
implementation performs an <pre>AuthPermission("refreshCredential")</pre>
|
|
security check to ensure the caller has permission to refresh
|
|
the credential. </div>
|
|
<div class="section" id="api__Destroyable"><a name="api__Destroyable"><!-- --></a><h4 class="sectiontitle">Destroyable</h4> This <strong>interface</strong> provides
|
|
the capability of destroying the contents within a credential. The interface
|
|
has two abstract methods: <pre> boolean isDestroyed();</pre>
|
|
Determines if the credential has been destroyed. <pre> void destroy() throws DestroyFailedException;</pre>
|
|
Destroys and clears the information associated with this credential.
|
|
Subsequent calls to certain methods on this credential will result in an
|
|
<pre>IllegalStateException</pre>
|
|
being thrown. This method implementation performs an <pre>AuthPermission("destroyCredential")</pre>
|
|
security check to ensure the caller has permission to destroy
|
|
the credential.</div>
|
|
<div class="section" id="api__Authentication"><a name="api__Authentication"><!-- --></a><h4 class="sectiontitle">Authentication Classes</h4> To authenticate
|
|
a <pre>Subject</pre>
|
|
, the following steps are performed: <ol><li>An application instantiates a <pre>LoginContext</pre>
|
|
.</li>
|
|
<li>The <pre>LoginContext</pre>
|
|
consults a configuration to load all of the LoginModules configured
|
|
for that application.</li>
|
|
<li>The application invokes the LoginContext's <em>login</em> method.</li>
|
|
<li>The <em>login</em> method invokes all of the loaded LoginModules. Each
|
|
<pre>LoginModule</pre>
|
|
attempts to authenticate the <pre>Subject</pre>
|
|
. Upon success, LoginModules associate relevant Principals and
|
|
credentials with the <pre>Subject</pre>
|
|
.</li>
|
|
<li>The <pre>LoginContext</pre>
|
|
returns the authentication status to the application.</li>
|
|
<li>If authentication succeeded, the application retrieves the authenticated
|
|
<pre>Subject</pre>
|
|
from the <pre>LoginContext</pre>
|
|
.</li>
|
|
</ol>
|
|
</div>
|
|
<div class="section" id="api__LoginContext"><a name="api__LoginContext"><!-- --></a><h4 class="sectiontitle">LoginContext</h4> The <pre>LoginContext</pre>
|
|
class provides the basic methods used to authenticate Subjects,
|
|
and provides a way to develop an application independent of the underlying
|
|
authentication technology. The <pre>LoginContext</pre>
|
|
consults a configuration <pre>Configuration</pre>
|
|
to determine the authentication services, or LoginModules, configured
|
|
for a particular application. Therefore, different LoginModules can be plugged
|
|
in under an application without requiring any modifications to the application
|
|
itself. <pre>LoginContext</pre>
|
|
offers four constructors to choose from: <pre> 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</pre>
|
|
All of the constructors share a common parameter: <em><strong> name</strong></em>.
|
|
This argument is used by the <pre>LoginContext</pre>
|
|
to index the login Configuration. Constructors that do not take
|
|
a <pre>Subject</pre>
|
|
as an input parameter instantiate a new <pre>Subject</pre>
|
|
. Null inputs are disallowed for all constructors. Callers require
|
|
an <pre>AuthPermission("createLoginContext")</pre>
|
|
to instantiate a <pre>LoginContext</pre>
|
|
. <p>Actual authentication occurs with a call to the following
|
|
method:</p>
|
|
<pre> public void login() throws LoginException;</pre>
|
|
When <em>login</em> is invoked, all of the configured LoginModules'
|
|
respective <em>login</em> methods are invoked to perform the authentication.
|
|
If the authentication succeeded, the authenticated <pre>Subject</pre>
|
|
(which may now hold Principals, public credentials, and private
|
|
credentials) can be retrieved by using the following method: <pre> public Subject getSubject();</pre>
|
|
To logout a <pre>Subject</pre>
|
|
and remove its authenticated Principals and credentials, the
|
|
following method is provided: <pre> public void logout() throws LoginException;</pre>
|
|
<p>The following snippet of code in an application will authenticate
|
|
a Subject called "bob" after accessing a configuration file with a configuration
|
|
entry named "moduleFoo":</p>
|
|
<pre> Subject bob = new Subject();
|
|
LoginContext lc = new LoginContext("moduleFoo", bob);
|
|
try {
|
|
lc.login();
|
|
System.out.println("authentication successful");
|
|
} catch (LoginException le) {
|
|
System.out.println("authentication unsuccessful"+le.printStackTrace());
|
|
}</pre>
|
|
This snippet of code in an application will authenticate a "nameless"
|
|
Subject and then use the getSubject method to retrieve it: <pre> LoginContext lc = new LoginContext("moduleFoo");
|
|
try {
|
|
lc.login();
|
|
System.out.println("authentication successful");
|
|
} catch (LoginException le) {
|
|
System.out.println("authentication unsuccessful"+le.printStackTrace());
|
|
}
|
|
Subject subject = lc.getSubject();</pre>
|
|
If the authentication failed, then <em>getSubject</em> returns
|
|
null. Also, there isn't an <pre>AuthPermission("getSubject")</pre>
|
|
required to do this as is the case for <pre>Subject.getSubject</pre>
|
|
</div>
|
|
<div class="section" id="api__LoginModule"><a name="api__LoginModule"><!-- --></a><h4 class="sectiontitle">LoginModule</h4><p>The LoginModule <strong>interface</strong> gives
|
|
developers the ability to implement different kinds of authentication technologies
|
|
that can be plugged under an application. For example, one type of</p>
|
|
<pre>LoginModule</pre>
|
|
may perform a username/password-based form of authentication.
|
|
<p>The <a href="http://java.sun.com/security/jaas/doc/module.html" target="_blank">LoginModule Developer's Guide</a> is a detailed document
|
|
that gives developers step-by-step instructions for implementing LoginModules.</p>
|
|
<p>To
|
|
instantiate a</p>
|
|
<pre>LoginModule</pre>
|
|
, a <pre>LoginContext</pre>
|
|
expects each <pre>LoginModule</pre>
|
|
to provide a public constructor that takes no arguments. Then,
|
|
to initialize a <pre>LoginModule</pre>
|
|
with the relevant information, a <pre>LoginContext</pre>
|
|
calls the LoginModule's <pre>initialize</pre>
|
|
method. The provided <em>subject</em> is guaranteed to be non-null.
|
|
<pre> void initialize(Subject subject, CallbackHandler callbackHandler,
|
|
Map sharedState, Map options);</pre>
|
|
This following method begins the authentication process: <pre> boolean login() throws LoginException;</pre>
|
|
An example method implementation may prompt the user for a username
|
|
and password, and then verify the information against the data stored in a
|
|
naming service such as NIS or LDAP. Alternative implementations might interface
|
|
smart cards and biometric devices, or may simply extract user information
|
|
from the underlying operating system. This is considered <em><strong>phase 1</strong></em> of
|
|
the JAAS authentication process. <p>The following method completes and finalizes
|
|
the authentication process:</p>
|
|
<pre> boolean commit() throws LoginException;</pre>
|
|
If <em><strong>phase 1</strong></em> of the authentication process was successful,
|
|
then this method continues with <em><strong>phase 2</strong></em>: associating Principals,
|
|
public credentials, and private credentials with the Subject. If <em><strong>phase
|
|
1</strong></em> failed, then the <em>commit</em> method removes any previously stored
|
|
authentication state, such as usernames and passwords. <p>The following
|
|
method halts the authentication process if <em> <strong>phase 1</strong></em> was unsuccessful:</p>
|
|
<pre> boolean abort() throws LoginException;</pre>
|
|
Typical implementations of this method clean up previously stored
|
|
authentication state, such as usernames or passwords. The following method
|
|
logs out a Subject: <pre> boolean logout() throws LoginException;</pre>
|
|
This method removes the Principals and credentials originally
|
|
associated with the <pre>Subject</pre>
|
|
during the <pre>commit</pre>
|
|
operation. Credentials are destroyed upon removal.</div>
|
|
<div class="section" id="api__CallbackHandler"><a name="api__CallbackHandler"><!-- --></a><h4 class="sectiontitle">CallbackHandler</h4><p>In some cases
|
|
a LoginModule must communicate with the user to obtain authentication information.
|
|
LoginModules use a CallbackHandler for this purpose. Applications implement
|
|
the CallbackHandler <strong>interface</strong> and pass it to the LoginContext, which
|
|
forwards it directly to the underlying LoginModules. LoginModules use 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 prompt the user
|
|
for input directly from the command line.</p>
|
|
<pre>CallbackHandler</pre>
|
|
is an <strong>interface</strong> with one method to implement: <pre> void handle(Callback[] callbacks)
|
|
throws java.io.IOException, UnsupportedCallbackException;</pre>
|
|
</div>
|
|
<div class="section" id="api__Callback"><a name="api__Callback"><!-- --></a><h4 class="sectiontitle">Callback</h4>The javax.security.auth.callback
|
|
package contains the Callback <strong>interface</strong> as well as several implementations.
|
|
LoginModules may pass an array of Callbacks directly to the <em> handle</em> method
|
|
of a CallbackHandler. <p>Consult the various Callback APIs for more information
|
|
on their use.</p>
|
|
</div>
|
|
<div class="section" id="api__Authorization"><a name="api__Authorization"><!-- --></a><h4 class="sectiontitle">Authorization Classes</h4> Upon successful
|
|
authentication of a <pre>Subject</pre>
|
|
, fine-grained access controls can be placed upon that <pre>Subject</pre>
|
|
by invoking the <a href="#api__doas">Subject.doAs</a> or <a href="#api__doaspriv">Subject.doAsPrivileged</a> methods. The permissions
|
|
granted to that <pre>Subject</pre>
|
|
are configured in a JAAS <pre>Policy</pre>
|
|
.</div>
|
|
<div class="section" id="api__Policy"><a name="api__Policy"><!-- --></a><h4 class="sectiontitle">Policy</h4> This is an <strong>abstract</strong> class
|
|
for representing the system-wide JAAS access control. As a default, JAAS provides
|
|
a file-based subclass implementation, PolicyFile. Each <pre>Policy</pre>
|
|
subclass must implement the following methods: <pre> public abstract java.security.PermissionCollection getPermissions
|
|
(Subject subject,
|
|
java.security.CodeSource cs);
|
|
public abstract void refresh();</pre>
|
|
The <pre>getPermissions</pre>
|
|
method returns the permissions granted to the specified <pre>Subject</pre>
|
|
and <pre>CodeSource</pre>
|
|
. The <pre>refresh</pre>
|
|
method updates the runtime <pre>Policy</pre>
|
|
with any modifications made since the last time it was loaded
|
|
from its permanent store (a file or database, for example). The <pre>refresh</pre>
|
|
method requires an <pre>AuthPermission("refreshPolicy")</pre>
|
|
. <p>The following method retrieves the current runtime</p>
|
|
<pre>Policy</pre>
|
|
object, and is protected with a security check that requires
|
|
the caller to have an <pre>AuthPermission("getPolicy")</pre>
|
|
. <pre> public static Policy getPolicy();</pre>
|
|
The following example code demonstrates how a <pre>Policy</pre>
|
|
object can be queried for the set of permissions granted to
|
|
the specified <pre>Subject</pre>
|
|
and <pre>CodeSource</pre>
|
|
: <pre> policy = Policy.getPolicy();
|
|
PermissionCollection perms = policy.getPermissions(subject, codeSource);</pre>
|
|
To set a new <pre>Policy</pre>
|
|
object for the Java runtime, the <pre>Policy.setPolicy</pre>
|
|
method may be used. This method requires the caller to have
|
|
an <pre>AuthPermission("setPolicy")</pre>
|
|
. <pre> public static void setPolicy(Policy policy);</pre>
|
|
<p><strong>Policy File Sample Entries:</strong></p>
|
|
<p>These examples
|
|
are relevant only for the default PolicyFile implementation.</p>
|
|
<p>Each
|
|
entry in the</p>
|
|
<pre>Policy</pre>
|
|
is represented as a <strong><em>grant</em></strong> entry. Each <strong><em>grant</em></strong> entry
|
|
specifies a codebase/code-signers/Principals triplet, as well as the Permissions
|
|
granted to that triplet. Specifically, the permissions will be granted to
|
|
any code downloaded from the specified <em> codebase</em> and signed by the
|
|
specified <em>code signers</em>, so long as the <pre>Subject</pre>
|
|
running that code has all of the specified <em>Principals</em> in
|
|
its <pre>Principal</pre>
|
|
set. Refer to the <a href="#api__doas">Subject.doAs examples</a> to
|
|
see how a <pre>Subject</pre>
|
|
becomes associated with running code. <pre> grant CodeBase ["URL"],
|
|
Signedby ["signers"],
|
|
Principal [Principal_Class] "Principal_Name",
|
|
Principal ... {
|
|
permission Permission_Class ["Target_Name"]
|
|
[, "Permission_Actions"]
|
|
[, signedBy "SignerName"];
|
|
};
|
|
|
|
// example grant entry
|
|
grant CodeBase "http://griffin.ibm.com", Signedby "davis",
|
|
Principal com.ibm.security.auth.NTUserPrincipal "kent" {
|
|
permission java.io.FilePermission "c:/kent/files/*", "read, write";
|
|
};</pre>
|
|
If no <em>Principal</em> information is specified in the JAAS <pre>Policy</pre>
|
|
grant entry, a parsing exception will be thrown. However, grant
|
|
entries that already exist in the regular Java 2 codesource-based policy file (and
|
|
therefore have no <em>Principal</em> information) are still valid. In those
|
|
cases, the <em>Principal</em> information is implied to be '*' (the grant entries
|
|
applies to all Principals). <p>The CodeBase and Signedby components of the
|
|
grant entry are optional in the JAAS</p>
|
|
<pre>Policy</pre>
|
|
. If they are not present, then any codebase will match, and
|
|
any signer (including unsigned code) will match. <p>In the example above,
|
|
the <strong><em>grant</em></strong> entry specifies that code downloaded from "http://griffin.ibm.com",
|
|
signed by "davis", and running as the NT user "kent", has one</p>
|
|
<pre>Permission</pre>
|
|
. This <pre>Permission</pre>
|
|
permits the processing code to read and write files in the directory
|
|
"c:\kent\files". <p>Multiple Principals may be listed within one <strong><em> grant</em></strong> entry.
|
|
The current</p>
|
|
<pre>Subject</pre>
|
|
running the code must have all of the specified Principals in
|
|
its <pre>Principal</pre>
|
|
set to be granted the entry's Permissions. <pre> grant Principal com.ibm.security.auth.NTUserPrincipal "kent",
|
|
Principal com.ibm.security.auth.NTSidGroupPrincipal "S-1-1-0" {
|
|
permission java.io.FilePermission "c:/user/kent/", "read, write";
|
|
permission java.net.SocketPermission "griffin.ibm.com", "connect";
|
|
};</pre>
|
|
This entry grants any code running as both the NT user "kent"
|
|
with the NT group identification number "S-1-1-0", permission to read and
|
|
write files in "c:\user\kent", as well as permission to make socket connections
|
|
to "griffin.ibm.com". </div>
|
|
<div class="section" id="api__AuthPermission"><a name="api__AuthPermission"><!-- --></a><h4 class="sectiontitle">AuthPermission</h4> This 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 inherited methods (from
|
|
the <pre>Permission</pre>
|
|
class), an <pre>AuthPermission</pre>
|
|
has two public constructors: <pre> public AuthPermission(String name);
|
|
public AuthPermission(String name, String actions);</pre>
|
|
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 <em>actions</em> argument which
|
|
is currently unused and are null. This constructor exists solely for the
|
|
<pre>Policy</pre>
|
|
object to instantiate new Permission objects. For most code,
|
|
the first constructor is appropriate. <p>The AuthPermission object is used
|
|
to guard access to the Policy, Subject, LoginContext, and Configuration objects.
|
|
Refer to the AuthPermission Javadoc for the list of valid names that are supported.</p>
|
|
</div>
|
|
<div class="section" id="api__PrivateCredentialPermission"><a name="api__PrivateCredentialPermission"><!-- --></a><h4 class="sectiontitle">PrivateCredentialPermission</h4>This
|
|
class protects access to a Subject's private credentials and provides one
|
|
public constructor: <pre> public PrivateCredentialPermission(String name, String actions);</pre>
|
|
Refer to the PrivateCredentialPermission Javadoc for more detailed
|
|
information on this class.</div>
|
|
<div class="section" id="api__Implementation"><a name="api__Implementation"><!-- --></a><h4 class="sectiontitle">Implementation</h4>Note: <a href="#api__AppendixA">Appendix
|
|
A</a> contains a sample <strong>java.security</strong> file that includes the static
|
|
properties mentioned here. <p>Because there exists default values for JAAS
|
|
providers and policy files, users need not statically (in the java.security
|
|
file) nor dynamically (command line <em><strong>-D</strong></em> option) list their values
|
|
in order to implement JAAS. Also, the default configuration and policy file
|
|
providers may be replaced by a user-developed provider. Therefore this section
|
|
is an attempt to explain the JAAS default providers and policy files as well
|
|
as the properties that enable alternative providers.</p>
|
|
<p>Read the Default
|
|
Policy File API and Default Configuration File API for more information than
|
|
is summarized here.</p>
|
|
<p><strong>Authentication Provider</strong></p>
|
|
<p>The authentication
|
|
provider, or configuration class, is statically set with</p>
|
|
<pre>login.configuration.provider=[class]</pre>
|
|
in the <em>java.security</em> file. This provider creates the
|
|
<pre>Configuration</pre>
|
|
object. <p>For example:</p>
|
|
<pre> login.configuration.provider=com.foo.Config</pre>
|
|
If the Security property <pre>login.configuration.provider</pre>
|
|
is not found in java.security, then JAAS will set it to the
|
|
default value: <pre>com.ibm.security.auth.login.ConfigFile</pre>
|
|
. <p>If a security manager is set before the</p>
|
|
<pre>Configuration</pre>
|
|
is created, then an <pre>AuthPermission("getLoginConfiguration")</pre>
|
|
will be required to be granted. <p>There isn't a way to dynamically
|
|
set the configuration provider on the command line.</p>
|
|
<p><strong>Authentication
|
|
Configuration File</strong></p>
|
|
<p>The authentication configuration files may
|
|
be statically set in <em>java.security</em> with</p>
|
|
<pre>login.config.url.<em>n</em>=[URL]</pre>
|
|
, where <em>n</em> is a consecutively number integer starting
|
|
with 1. The format is identical to the format for Java security policy files (policy.url.n=[URL]).
|
|
<p>If the Security property</p>
|
|
<pre>policy.allowSystemProperty</pre>
|
|
is set to "true" in java.security, then users can dynamically
|
|
set policy files on the command line utilizing the <em><strong> -D</strong></em> option
|
|
with this property: <pre>java.security.auth.login.config</pre>
|
|
. The value may be a path or URL. For example (on NT): <pre> ... -Djava.security.auth.login.config=c:\config_policy\login.config ...
|
|
or
|
|
... -Djava.security.auth.login.config=file:c:/config_policy/login.config ...</pre>
|
|
Note: using double equal signs (==) on the command line allows
|
|
a user to override all other policy files found. <p>If no configuration
|
|
files can be found statically or dynamically, JAAS will try to load the configuration
|
|
file from this default location:</p>
|
|
<pre><em>${user.home}</em>\.java.login.config</pre>
|
|
where <em>${user.home}</em> is a system dependent location. <p id="api__authorprovider"><a name="api__authorprovider"><!-- --></a><strong>Authorization Provider</strong></p>
|
|
<p>The authorization
|
|
provider, or JAAS Policy class, is statically set with</p>
|
|
<pre>auth.policy.provider=[class]</pre>
|
|
in the <em>java.security</em> file. This provider creates the
|
|
JAAS Subject-based <pre>Policy</pre>
|
|
object. <p>For example:</p>
|
|
<pre> auth.policy.provider=com.foo.Policy</pre>
|
|
If the Security property <pre>auth.policy.provider</pre>
|
|
is not found in java.security, then JAAS will set it to the
|
|
default value: <pre>com.ibm.security.auth.PolicyFile</pre>
|
|
. <p>If a security manager is set before the</p>
|
|
<pre>Configuration</pre>
|
|
is created, then an <pre>AuthPermission("getPolicy")</pre>
|
|
will be required to be granted. <p>There isn't a way to dynamically
|
|
set the authorization provider on the command line.</p>
|
|
<p><strong>Authorization
|
|
Policy File</strong></p>
|
|
<p>The authorization policy files may be statically set
|
|
in <em> java.security</em> with</p>
|
|
<pre>auth.policy.url.<em>n</em>=[URL]</pre>
|
|
, where <em>n</em> is a consecutively number integer starting
|
|
with 1. The format is identical to the format for Java security policy files (policy.url.n=[URL]).
|
|
<p>If the Security property</p>
|
|
<pre>policy.allowSystemProperty</pre>
|
|
is set to "true" in java.security, then users can dynamically
|
|
set policy files on the command line utilizing the <em><strong> -D</strong></em> option
|
|
with this property: <pre>java.security.auth.policy</pre>
|
|
. The value may be a path or URL. For example (on NT): <pre> ... -Djava.security.auth.policy=c:\auth_policy\java.auth.policy ...
|
|
or
|
|
... -Djava.security.auth.policy=file:c:/auth_policy/java.auth.policy ...</pre>
|
|
Note: using double equal signs (==) on the command line allows
|
|
a user to override all other policy files found. <p>There is not a default
|
|
location to load an authorization policy from.</p>
|
|
</div>
|
|
<div class="section" id="api__HelloWorld"><a name="api__HelloWorld"><!-- --></a><h4 class="sectiontitle">"Hello World", JAAS style!</h4> <p>Put
|
|
on your dark sunglasses and favorite fedora hat, then grab an alto sax ...
|
|
it's time to get <strong>JAAS</strong>-y! Yes, another "Hello World!" program. In this
|
|
section, a program will be made available to test your JAAS installation.</p>
|
|
<p><strong>Installation</strong> It
|
|
is assumed that JAAS has been installed. For example, the JAAS JAR files have
|
|
been copied to your Development Kit's extensions directory.</p>
|
|
<p><strong>Retrieve
|
|
Files</strong> Download theHelloWorld.tar to your test directory. Expand it using
|
|
"jar xvf HelloWorld.tar".</p>
|
|
<p>Verify the contents of your test directory.</p>
|
|
<strong>source
|
|
files</strong>: <ul><li>HWLoginModule.java</li>
|
|
<li>HWPrincipal.java</li>
|
|
<li>HelloWorld.java</li>
|
|
</ul>
|
|
<strong>class files</strong> <ul><li>The source files have been precompiled for you into the classes directory.</li>
|
|
</ul>
|
|
<strong>policy files</strong> <ul><li>jaas.config</li>
|
|
<li>java2.policy</li>
|
|
<li>jaas.policy</li>
|
|
</ul>
|
|
<p><strong>Compile Source Files</strong> The three source files, <em><strong>HWLoginModule.java</strong></em>, <em><strong>HWPrincipal.java</strong></em> and <em><strong> HelloWorld.java</strong></em>, are already compiled and therefore do not need to be compiled.</p>
|
|
<p>If
|
|
any of the source files are modified, then change to the test directory that
|
|
they were saved to and enter:</p>
|
|
<pre>javac -d .\classes *.java</pre>
|
|
The classpath needs the classes directory (.\classes) added
|
|
to it in order to compile the classes. <p>Note:</p>
|
|
<pre>HWLoginModule</pre>
|
|
and <pre>HWPrincipal</pre>
|
|
are in the <pre>com.ibm.security</pre>
|
|
package and will be created in the appropriate directory during
|
|
compilation (>test_dir<\classes\com\ibm\security). <p><strong>Examine Policy
|
|
Files</strong> The configuration file, <em><strong>jaas.config</strong></em>, contains one
|
|
entry:</p>
|
|
<pre>helloWorld {
|
|
com.ibm.security.HWLoginModule required debug=true;
|
|
};</pre>
|
|
Only one <pre>LoginModule</pre>
|
|
is supplied with the test case. When processing the <em><strong> HelloWorld</strong></em> application,
|
|
experiment by changing the <pre>LoginModuleControlFlag</pre>
|
|
(required, requisite, sufficient, optional) and deleting the
|
|
debug flag. If more LoginModules are available for testing, then feel free
|
|
to alter this configuration and experiment with multiple LoginModules. <pre>HWLoginModule</pre>
|
|
will be discussed shortly. <p>The Java 2 policy file, <em><strong>java2.policy</strong></em>,
|
|
contains one permission block:</p>
|
|
<pre>grant {
|
|
permission javax.security.auth.AuthPermission "createLoginContext";
|
|
permission javax.security.auth.AuthPermission "modifyPrincipals";
|
|
permission javax.security.auth.AuthPermission "doAsPrivileged";
|
|
};</pre>
|
|
The three permissions are required because the <em><strong> HelloWorld</strong></em> application
|
|
(1) creates a LoginContext object, (2) modifies the Principals of the the
|
|
authenticated <pre>Subject</pre>
|
|
and (3) calls the doAsPrivileged method of the <pre>Subject</pre>
|
|
class. <p>The JAAS policy file, <em><strong>jaas.policy</strong></em>,
|
|
also contains one permission block:</p>
|
|
<pre>grant Principal com.ibm.security.HWPrincipal "bob" {
|
|
permission java.util.PropertyPermission "java.home", "read";
|
|
permission java.util.PropertyPermission "user.home", "read";
|
|
permission java.io.FilePermission "foo.txt", "read";
|
|
};</pre>
|
|
The three permissions are initially granted to an <pre>HWPrincipal</pre>
|
|
named <em><strong>bob</strong></em>. The actual Principal added to the authenticated
|
|
<pre>Subject</pre>
|
|
is the username used during the login process (more later). <p id="api__action"><a name="api__action"><!-- --></a></p>
|
|
Here's the action code from <em><strong>HelloWorld</strong></em> with
|
|
the three system calls (the reason for the required permissions) in <strong>bold</strong>:
|
|
<pre>Subject.doAsPrivileged(lc.getSubject(), new PrivilegedAction() {
|
|
public Object run() {
|
|
System.out.println("\nYour java.home property: "
|
|
+<strong>System.getProperty("java.home")</strong>);
|
|
|
|
System.out.println("\nYour user.home property: "
|
|
+<strong>System.getProperty("user.home")</strong>);
|
|
|
|
File f = new File("foo.txt");
|
|
System.out.print("\nfoo.txt does ");
|
|
if (<strong>!f.exists()</strong>) System.out.print("not ");
|
|
System.out.println("exist in your current directory");
|
|
|
|
System.out.println("\nOh, by the way ...");
|
|
|
|
try {
|
|
Thread.currentThread().sleep(2000);
|
|
} catch (Exception e) {
|
|
// ignore
|
|
}
|
|
System.out.println("\n\nHello World!\n");
|
|
return null;
|
|
}
|
|
}, null);</pre>
|
|
When running the <em><strong>HelloWorld</strong></em> program, use various
|
|
usernames and alter <em><strong>jaas.policy</strong></em> accordingly. There is no need
|
|
to alter <em><strong> java2.policy</strong></em>. Also, create a file called <em><strong> foo.txt</strong></em> in
|
|
the test directory to test the last system call. <p><strong>Examine Source Files</strong> The
|
|
LoginModule,</p>
|
|
<pre>HWLoginModule</pre>
|
|
, authenticates any user who enters the correct password (case
|
|
sensitive): <strong>Go JAAS</strong>. <p>The <em><strong>HelloWorld</strong></em> application
|
|
permits users three attempts to do so. When <strong>Go JAAS</strong> is correctly entered,
|
|
an</p>
|
|
<pre>HWPrincipal</pre>
|
|
with a name equal the the username is added to the authenticated
|
|
<pre>Subject</pre>
|
|
. <p>The Principal class,</p>
|
|
<pre>HWPrincipal</pre>
|
|
, represents a Principal based on the username entered. It is
|
|
this name that is important when granting permissions to authenticated Subjects.
|
|
<p>The main application,</p>
|
|
<pre>HelloWorld</pre>
|
|
, first creates a <pre>LoginContext</pre>
|
|
based on a configuration entry with the name <strong> helloWorld</strong>.
|
|
The configuration file has already been discussed. Callbacks are used to retrieve
|
|
user input. Look at the <pre>MyCallbackHandler</pre>
|
|
class located in the <em><strong>HelloWorld.java</strong></em> file to see
|
|
this process. <pre> LoginContext lc = null;
|
|
try {
|
|
lc = new LoginContext("helloWorld", new MyCallbackHandler());
|
|
} catch (LoginException le) {
|
|
le.printStackTrace();
|
|
System.exit(-1);
|
|
}</pre>
|
|
The user enters a username/password (up to three times) and
|
|
if <strong>Go JAAS</strong> is entered as the password, then the Subject is authenticated
|
|
( <pre>HWLoginModule</pre>
|
|
adds a <pre>HWPrincipal</pre>
|
|
to the Subject). <p>As mentioned previously, <a href="#api__action">work
|
|
is then performed as the authenticated Subject.</a></p>
|
|
<p><strong>Run HelloWorld
|
|
Test</strong></p>
|
|
<p>To run the <em><strong>HelloWorld</strong></em> program, first change
|
|
to the test directory. The configuration and policy files will need to be
|
|
loaded. See <a href="#api__Implementation"> Implementation</a> for the
|
|
correct properties to set either in <em> java.security</em> or on the command
|
|
line. The latter method will be discussed here.</p>
|
|
<p>The following command
|
|
has been broken up into several lines for clarity. Enter as one continuous
|
|
command.</p>
|
|
<pre>java -Djava.security.manager=
|
|
-Djava.security.auth.login.config=.\jaas.config
|
|
-Djava.security.policy=.\java2.policy
|
|
-Djava.security.auth.policy=.\jaas.policy
|
|
HelloWorld</pre>
|
|
Note: the use of ".\filename" for the policy files is necessary
|
|
because each user's test directory canonical path will vary. If desired, substitute
|
|
"." with the path to the test directory. For example, if the test directory
|
|
is "c:\test\hello", then the first file is changed to: <pre> -Djava.security.auth.login.config=c:\test\hello\jaas.config</pre>
|
|
If the policy files are not found, a <pre>SecurityException</pre>
|
|
will be thrown. Otherwise, information concerning your <em><strong> java.home</strong></em> and <em><strong>user.home</strong></em> properties
|
|
will be displayed. Also, the existence of a file called <em><strong>foo.txt</strong></em> in
|
|
your test directory will be checked. Finally, the ubiquitous "Hello World"
|
|
message is displayed. <p><strong>Having Fun With HelloWorld</strong></p>
|
|
<p>Rerun <em><strong>HelloWorld</strong></em> as
|
|
many times as you like. It has already been suggested to vary the username/passwords
|
|
entered, change the configuration file entries, change the policy file permissions,
|
|
and to even add (stack) additional LoginModules to the <em><strong>helloWorld</strong></em> configuration
|
|
entry. You could add codebase fields to the policy files too.</p>
|
|
<p>Finally,
|
|
try running the program without a SecurityManager to see how it works if you
|
|
run into problems.</p>
|
|
</div>
|
|
<div class="section" id="api__AppendixA"><a name="api__AppendixA"><!-- --></a><h4 class="sectiontitle">Appendix A: JAAS Settings in the java.security
|
|
Security Properties File</h4> <p>Below is a copy of the</p>
|
|
<pre>java.security</pre>
|
|
file that appears in every Java 2 installation. This file appears in
|
|
the <pre>lib/security</pre>
|
|
( <pre>lib\security</pre>
|
|
on Windows<sup>®</sup>) directory of the Java 2 runtime. Thus, if the Java 2
|
|
runtime is installed in a directory called <pre>jdk1.3</pre>
|
|
, the file is <ul><li> <pre>jdk1.3/lib/security/java.security</pre>
|
|
(Unix)</li>
|
|
<li> <pre>jdk1.3\lib\security\java.security</pre>
|
|
(Windows)</li>
|
|
</ul>
|
|
JAAS adds four new properties to <pre>java.security</pre>
|
|
: <ul><li>Authentication Properties <ul><li> <pre>login.configuration.provider</pre>
|
|
</li>
|
|
<li> <pre>login.policy.url.n</pre>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li>Authorization Properties <ul><li> <pre>auth.policy.provider</pre>
|
|
</li>
|
|
<li> <pre>auth.policy.url.n</pre>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
<p>The new JAAS properties are located at the end of this file:</p>
|
|
<pre>#
|
|
# This is the "master security properties file".
|
|
#
|
|
# In this file, various security properties are set for use by
|
|
# java.security classes. This is where users can statically register
|
|
# Cryptography Package Providers ("providers" for short). The term
|
|
# "provider" refers to a package or set of packages that supply a
|
|
# concrete implementation of a subset of the cryptography aspects of
|
|
# the Java Security API. A provider may, for example, implement one or
|
|
# more digital signature algorithms or message digest algorithms.
|
|
#
|
|
# Each provider must implement a subclass of the Provider class.
|
|
# To register a provider in this master security properties file,
|
|
# specify the Provider subclass name and priority in the format
|
|
#
|
|
# security.provider.n=className
|
|
#
|
|
# This declares a provider, and specifies its preference
|
|
# order n. The preference order is the order in which providers are
|
|
# searched for requested algorithms (when no specific provider is
|
|
# requested). The order is 1-based; 1 is the most preferred, followed
|
|
# by 2, and so on.
|
|
#
|
|
# className must specify the subclass of the Provider class whose
|
|
# constructor sets the values of various properties that are required
|
|
# for the Java Security API to look up the algorithms or other
|
|
# facilities implemented by the provider.
|
|
#
|
|
# There must be at least one provider specification in java.security.
|
|
# There is a default provider that comes standard with the JDK. It
|
|
# is called the "SUN" provider, and its Provider subclass
|
|
# named Sun appears in the sun.security.provider package. Thus, the
|
|
# "SUN" provider is registered via the following:
|
|
#
|
|
# security.provider.1=sun.security.provider.Sun
|
|
#
|
|
# (The number 1 is used for the default provider.)
|
|
#
|
|
# Note: Statically registered Provider subclasses are instantiated
|
|
# when the system is initialized. Providers can be dynamically
|
|
# registered instead by calls to either the addProvider or
|
|
# insertProviderAt method in the Security class.
|
|
|
|
#
|
|
# List of providers and their preference orders (see above):
|
|
#
|
|
security.provider.1=sun.security.provider.Sun
|
|
|
|
#
|
|
# Class to instantiate as the system Policy. This is the name of the class
|
|
# that will be used as the Policy object.
|
|
#
|
|
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}/lib/security/java.policy
|
|
policy.url.2=file:${user.home}/.java.policy
|
|
|
|
# whether or not we expand properties in the policy file
|
|
# if this is set to false, properties (${...}) will not be expanded in policy
|
|
# files.
|
|
policy.expandProperties=true
|
|
|
|
# whether or not we allow an extra policy to be passed on the command line
|
|
# with -Djava.security.policy=somefile. Comment out this line to disable
|
|
# this feature.
|
|
policy.allowSystemProperty=true
|
|
|
|
# whether or not we look into the IdentityScope for trusted Identities
|
|
# when encountering a 1.1 signed JAR file. If the identity is found
|
|
# and is trusted, we grant it AllPermission.
|
|
policy.ignoreIdentityScope=false
|
|
|
|
#
|
|
# Default keystore type.
|
|
#
|
|
keystore.type=jks
|
|
|
|
#
|
|
# Class to instantiate as the system scope:
|
|
#
|
|
system.scope=sun.security.provider.IdentityDatabase
|
|
|
|
##############################################################################
|
|
#
|
|
# Java Authentication and Authorization Service (JAAS)
|
|
# properties and policy files:
|
|
#
|
|
|
|
# Class to instantiate as the system Configuration for authentication.
|
|
# This is the name of the class that will be used as the Authentication
|
|
# Configuration object.
|
|
#
|
|
login.configuration.provider=com.ibm.security.auth.login.ConfigFile
|
|
|
|
# The default is to have a system-wide login configuration file found in
|
|
# the user's home directory. For multiple files, the format is similar to
|
|
# that of CodeSource-base policy files above, that is policy.url.n
|
|
login.config.url.1=file:${user.home}/.java.login.config
|
|
|
|
# Class to instantiate as the system Principal-based Authorization Policy.
|
|
# This is the name of the class that will be used as the Authorization
|
|
# Policy object.
|
|
#
|
|
auth.policy.provider=com.ibm.security.auth.PolicyFile
|
|
|
|
# The default is to have a system-wide Principal-based policy file found in
|
|
# the user's home directory. For multiple files, the format is similar to
|
|
# that of CodeSource-base policy files above, that is policy.url.n and
|
|
# auth.policy.url.n
|
|
auth.policy.url.1=file:${user.home}/.java.auth.policy</pre>
|
|
</div>
|
|
<div class="section" id="api__AppendixB"><a name="api__AppendixB"><!-- --></a><h4 class="sectiontitle">Appendix B: Login Configuration Files</h4>A
|
|
login configuration file contains one or more <pre>LoginContext</pre>
|
|
application names which have the following form: <pre>Application {
|
|
LoginModule Flag ModuleOptions;
|
|
> more LoginModule entries <
|
|
LoginModule Flag ModuleOptions;
|
|
};</pre>
|
|
Login configuration files are located using the <pre>login.config.url.n</pre>
|
|
security property found in the <pre>java.security</pre>
|
|
file. For more information about this property and the location
|
|
of the <pre>java.security</pre>
|
|
file, see <a href="#api__AppendixA">Appendix A</a>. <p>The <em>Flag</em> value
|
|
controls the overall behavior as authentication proceeds down the stack. The
|
|
following represents a description of the valid values for <em>Flag</em> and
|
|
their respective semantics:</p>
|
|
<ol><li><strong>Required</strong> The <pre>LoginModule</pre>
|
|
is required to succeed. If it succeeds or fails, authentication
|
|
still continues to proceed down the <pre>LoginModule</pre>
|
|
list.</li>
|
|
<li><strong>Requisite</strong> The <pre>LoginModule</pre>
|
|
is required to succeed. If it succeeds, authentication continues
|
|
down the <pre>LoginModule</pre>
|
|
list. If it fails, control immediately returns to the application
|
|
(authentication does not proceed down the <pre>LoginModule</pre>
|
|
list).</li>
|
|
<li><strong>Sufficient</strong> The <pre>LoginModule</pre>
|
|
is not required to succeed. If it does succeed, control immediately
|
|
returns to the application (authentication does not proceed down the <pre>LoginModule</pre>
|
|
list). If it fails, authentication continues down the <pre>LoginModule</pre>
|
|
list.</li>
|
|
<li><strong>Optional</strong> The <pre>LoginModule</pre>
|
|
is not required to succeed. If it succeeds or fails, authentication
|
|
still continues to proceed down the <pre>LoginModule</pre>
|
|
list.</li>
|
|
</ol>
|
|
<p>The overall authentication succeeds only if all <em>Required</em> and <em>Requisite</em> LoginModules
|
|
succeed. If a <em> Sufficient</em></p>
|
|
<pre>LoginModule</pre>
|
|
is configured and succeeds, then only the <em>Required</em> and <em>Requisite</em> LoginModules
|
|
prior to that <em>Sufficient</em> <pre>LoginModule</pre>
|
|
need to have succeeded for the overall authentication to succeed.
|
|
If no <em>Required</em> or <em>Requisite</em> LoginModules are configured for
|
|
an application, then at least one <em>Sufficient</em> or <em>Optional</em> <pre>LoginModule</pre>
|
|
must succeed. <p><strong>Sample Configuration File:</strong></p>
|
|
<pre>/* Sample Configuration File */
|
|
|
|
Login1 {
|
|
com.ibm.security.auth.module.SampleLoginModule required debug=true;
|
|
};
|
|
|
|
Login2 {
|
|
com.ibm.security.auth.module.SampleLoginModule required;
|
|
com.ibm.security.auth.module.NTLoginModule sufficient;
|
|
ibm.loginModules.SmartCard requisite debug=true;
|
|
ibm.loginModules.Kerberos optional debug=true;
|
|
};</pre>
|
|
Note: the Flags are not case sensitive. <em>REQUISITE = requisite
|
|
= Requisite.</em> <p><strong>Login1</strong> only has one LoginModule which is an instance
|
|
of the class</p>
|
|
<pre>com.ibm.security.auth.module.SampleLoginModule</pre>
|
|
. Therefore, a <pre>LoginContext</pre>
|
|
associated with <strong>Login1</strong> will have a successful authentication
|
|
if and only if its lone module successfully authenticates. The <em>Required</em> flag
|
|
is trivial in this example; flag values have a relevant effect on authentication
|
|
when two or more modules are present. <p><strong>Login2</strong> is easier to explain
|
|
with a table.</p>
|
|
|
|
<div class="tablenoborder"><table cellpadding="4" cellspacing="0" summary="" width="100%" frame="border" border="1" rules="all"><thead align="left"><tr><th colspan="10" align="left" valign="top" id="d0e1889">Login2 Authentication Status</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody><tr><td valign="top" headers="d0e1889 ">Sample Login Module</td>
|
|
<td valign="top" headers="d0e1889 ">required</td>
|
|
<td valign="top" headers="d0e1889 ">pass</td>
|
|
<td valign="top" headers="d0e1889 ">pass</td>
|
|
<td valign="top" headers="d0e1889 ">pass</td>
|
|
<td valign="top" headers="d0e1889 ">pass</td>
|
|
<td valign="top" headers="d0e1889 ">fail</td>
|
|
<td valign="top" headers="d0e1889 ">fail</td>
|
|
<td valign="top" headers="d0e1889 ">fail</td>
|
|
<td valign="top" headers="d0e1889 ">fail</td>
|
|
</tr>
|
|
<tr><td valign="top" headers="d0e1889 ">NT Login Module</td>
|
|
<td valign="top" headers="d0e1889 ">sufficient</td>
|
|
<td valign="top" headers="d0e1889 ">pass</td>
|
|
<td valign="top" headers="d0e1889 ">fail</td>
|
|
<td valign="top" headers="d0e1889 ">fail</td>
|
|
<td valign="top" headers="d0e1889 ">fail</td>
|
|
<td valign="top" headers="d0e1889 ">pass</td>
|
|
<td valign="top" headers="d0e1889 ">fail</td>
|
|
<td valign="top" headers="d0e1889 ">fail</td>
|
|
<td valign="top" headers="d0e1889 ">fail</td>
|
|
</tr>
|
|
<tr><td valign="top" headers="d0e1889 ">Smart Card</td>
|
|
<td valign="top" headers="d0e1889 ">requisite</td>
|
|
<td valign="top" headers="d0e1889 ">*</td>
|
|
<td valign="top" headers="d0e1889 ">pass</td>
|
|
<td valign="top" headers="d0e1889 ">pass</td>
|
|
<td valign="top" headers="d0e1889 ">fail</td>
|
|
<td valign="top" headers="d0e1889 ">*</td>
|
|
<td valign="top" headers="d0e1889 ">pass</td>
|
|
<td valign="top" headers="d0e1889 ">pass</td>
|
|
<td valign="top" headers="d0e1889 ">fail</td>
|
|
</tr>
|
|
<tr><td valign="top" headers="d0e1889 ">Kerberos</td>
|
|
<td valign="top" headers="d0e1889 ">optional</td>
|
|
<td valign="top" headers="d0e1889 ">*</td>
|
|
<td valign="top" headers="d0e1889 ">pass</td>
|
|
<td valign="top" headers="d0e1889 ">fail</td>
|
|
<td valign="top" headers="d0e1889 ">*</td>
|
|
<td valign="top" headers="d0e1889 ">*</td>
|
|
<td valign="top" headers="d0e1889 ">pass</td>
|
|
<td valign="top" headers="d0e1889 ">fail</td>
|
|
<td valign="top" headers="d0e1889 ">*</td>
|
|
</tr>
|
|
<tr><td colspan="2" valign="top" headers="d0e1889 ">Overall Authentication</td>
|
|
<td valign="top" headers="d0e1889 ">pass</td>
|
|
<td valign="top" headers="d0e1889 ">pass</td>
|
|
<td valign="top" headers="d0e1889 ">pass</td>
|
|
<td valign="top" headers="d0e1889 ">fail</td>
|
|
<td valign="top" headers="d0e1889 ">fail</td>
|
|
<td valign="top" headers="d0e1889 ">fail</td>
|
|
<td valign="top" headers="d0e1889 ">fail</td>
|
|
<td valign="top" headers="d0e1889 ">fail</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
* = trivial value due to control returning to the application because
|
|
a previous <em>REQUISITE</em> module failed or a previous <em> SUFFICIENT</em> module
|
|
succeeded.</div>
|
|
<div class="section" id="api__AppendixC"><a name="api__AppendixC"><!-- --></a><h4 class="sectiontitle">Appendix C: Authorization Policy File</h4><p>
|
|
In case there weren't enough examples of Principal-based JAAS Policy grant
|
|
blocks above, here are some more. </p>
|
|
<pre><strong>// SAMPLE JAAS POLICY FILE: java.auth.policy
|
|
|
|
// The following permissions are granted to Principal 'Pooh' and all codesource:</strong>
|
|
|
|
grant Principal com.ibm.security.Principal "Pooh" {
|
|
permission javax.security.auth.AuthPermission "setPolicy";
|
|
permission java.util.PropertyPermission "java.home", "read";
|
|
permission java.util.PropertyPermission "user.home", "read";
|
|
permission java.io.FilePermission "c:/foo/jaas.txt", "read";
|
|
};
|
|
|
|
<strong>// The following permissions are granted to Principal 'Pooh' AND 'Eyeore'
|
|
// and CodeSource signedBy "DrSecure":</strong>
|
|
|
|
grant signedBy "DrSecure"
|
|
Principal com.ibm.security.Principal "Pooh",
|
|
Principal com.ibm.security.Principal "Eyeore" {
|
|
permission javax.security.auth.AuthPermission "modifyPublicCredentials";
|
|
permission javax.security.auth.AuthPermission "modifyPrivateCredentials";
|
|
permission java.net.SocketPermission "us.ibm.com", "connect,accept,resolve";
|
|
permission java.net.SocketPermission "griffin.ibm.com", "accept";
|
|
};
|
|
|
|
<strong>// The following permissions are granted to Principal 'Pooh' AND 'Eyeore' AND
|
|
// 'Piglet' and CodeSource from the c:\jaas directory signed by "kent" and "bruce":</strong>
|
|
|
|
grant codeBase "file:c:/jaas/*",
|
|
signedBy "kent, bruce",
|
|
Principal com.ibm.security.Principal "Pooh",
|
|
Principal com.ibm.security.Principal "Eyeore",
|
|
Principal com.ibm.security.Principal "Piglet" {
|
|
permission javax.security.auth.AuthPermission "getSubject";
|
|
permission java.security.SecurityPermission "printIdentity";
|
|
permission java.net.SocketPermission "guapo.ibm.com", "accept";
|
|
};</pre>
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<div class="familylinks">
|
|
<div class="parentlink"><strong>Parent topic:</strong> <a href="jaasbase.htm" title="The Java Authentication and Authorization Service (JAAS) is a standard extension to the Java 2 Software Development Kit (J2SDK), Standard Edition. J2SDK provides access controls that are based on where the code originated and who signed the code (code source-based access controls). It lacks, however, the ability to enforce additional access controls based on who runs the code. JAAS provides a framework that adds this support to the Java 2 security model.">Java Authentication and Authorization Service</a></div>
|
|
</div>
|
|
<div class="relconcepts"><strong>Related concepts</strong><br />
|
|
<div><a href="jaassamp.htm" title="This topic contains samples of Java Authentication and Authorization Service (JAAS) on an iSeries server.">Java Authentication and Authorization Service samples</a></div>
|
|
</div>
|
|
<div class="reltasks"><strong>Related tasks</strong><br />
|
|
<div><a href="jaasprep.htm" title="You must meet software requirements and configure your iSeries server to use Java Authentication and Authorization Service (JAAS).">Prepare and configure an iSeries server for Java Authentication and Authorization Service</a></div>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html> |