Java is a trademark and Java 2 is a registered trademark of Sun Microsystems Inc.
JAAS
Java Authentication
and Authorization
Services
Bruce A Rich
Java Security Lead
IBM/Tivoli Systems
Java, Java 2 are trademarks or
registered trademarks of Sun
Microsystems Inc.
Windows 2000 is a registered
trademark of Microsoft
Trademarks
JAAS fundamentals
JAAS case study with Kerberos
Backup materials
Java2 security model
JAAS and J2EE relationships
Talk Outline
JAAS fundamentals
Add the concept of "user identity" to
the Java 2 security model
Enable existing security services to
plug in
Compatibly extend the current
model
What is JAAS?
What is JAAS?
Key elements
Key elements
Authentication framework
Assertion of identity
Enhanced authorization
Low level of binding between
authentication and authorization
Authentication framework
Authentication framework
Authentication framework
Policy-based
Generic and abstract
Sufficient for today's mechanisms,
extensible
Pluggable, stackable
Key abstractions
Subject - any user of computing
Collection of Principals, credentials
Principal (java.security)
Assertion of identity
Assertion of identity
Avoids incompatible behavior
Lexically scopes identity
Logically associates Subject with current
Thread
Enhanced Authorization
Enhanced Authorization
Augmentation of current Permission
specification
Principal-based
Any authentication with any Permission
Example in Kerberos section
Local or remote code (signed or unsigned) Domain A JVM Sandbox Resources Domain C Domain B Security Policy Ability to grant specific permissions
to a particular piece of code
about accessing specific resources on the client, depending on the signer of the code
and/or the location from which the code was loaded.
Java 2 Security Model
Java 2 Permission Model
Java 2 Permission Model
Class A's Protection Domain
Class A
SecureClassLoader
POLICY
Certificate 1
Certificate 2 Code Base URL Code Source Permission 1 Permission 1 Permission 2 ... Permission Collection Permission M ... Protection Domain Certificate N
Java 2 Authorization Model
Java 2 Authorization Model
Cert 1,I
Cert 1,2 Code Base URL Code Source ... Permission Collection ... Cert 1,N Cert 2,1
Cert 2,2 Code Base URL Code Source
...
Cert 2,N
Cert K,1
Cert K,2 Code Base URL Code Source ... Cert K,N Class 1 Class 2
...
Class K...
Permission to check 1 2 K Perm 1,1 Perm 1,2 Perm 1,M1 ... Perm 2,1 Perm 2,2 Perm 2,M2 ... Perm K,1 Perm K,2 Perm K,MK Permission Collection Permission CollectionJAAS Authorization Model
JAAS Authorization Model
Class A's Protection Domain Class A
SecureClassLoader
POLICY
Certificate 1
Certificate 2 Code Base
URL Code Source Permission 1 Permission 1 Permission 2 ... Permission Collection Permission M ... Protection Domain Certificate N Permission 1 Permission 2 ... Permission Collection Permission M
Subject Y's Protection Domain
POLICY
JAAS
Building blocks
Building blocks
LoginModule
5 methods
New java.security.Principal subclass
Allows granting Permissions based on
this new Principal class
Possibly some "credentials" related to
Principal
Kerberos Authentication
Kerberos Authentication
Using JAAS
Using JAAS
KerberosUserPrincipal
Allows permissions based on this
authentication technique
KerberosTGTCredential
Allows further service acquisition without
requiring password
KerberosUserPrincipal
KerberosUserPrincipal
public class KerberosUserPrincipal extends Principal
{
private String name;
// user name
public KerberosUserPrincipal(String userName) {
name = userName
}
public String getName() {
return name;
}
. . .
KerberosTGTCredential
KerberosTGTCredential
public class KerberosTGTCredential extends Object
{
private KrbCreds creds;
public KerberosTGTCredential(KrbCreds creds) {
this.creds = creds
};
public KrbCreds getCreds() {
return creds;
}
. . .
}
KerberosLoginModule
KerberosLoginModule
public KerberosLoginModule extends LoginModule { private KerberosUserPrincipal kup;
private KerberosTGTCredential ktc; private Subject subj;
public void initialize (Subject s...) { subj=s; ... } public boolean login() {
if (callbackHandler == null) { // no way to get parameters??? } else {
get username, pw, realm;
authenticate, remember kup and tkc; }
}
public boolean commit() {
subj.getPrincipals.add(kup);
subj.getPublicCredentials.add(ktc);
}
If in a Windows 2000 domain, already have a Kerberos ticket, but how to use from Java?
New wrinkle for KerberosLoginModule LSACallAuthenticationPackage
KerbRetrieveEncodedTicketMessage + lots of JNI magic
=== KerberosTGTCredential for current Subject
Windows 2000 Interoperability
Permissions using Kerberos
Permissions using Kerberos
grant signedBy "mykey", codeBase "file:E:/Solutions/app/*"
principal
com.ibm.security.auth.KerberosUserPrincipal "brich"
{
permission com.ebank.AccountAccess "CloseAccount"; };
Configuring to use Kerberos
Configuring to use Kerberos
testKerberosAL {
com.ibm.security.auth.KerberosLoginModule required debug=true;
};...login configuration file
...
LoginContext lc = new LoginContext("testKerberosAL"); lc.login();
Subject whoami = lc.getSubject();
Subject.doAs(lc.getSubject(), someActionInstance); ...
Summary
Summary
JAAS extends base security
model to accomodate concept
of "users"
Pluggable, extensible
Kerberos provides an excellent
illustration of the power and
ease of using JAAS to extend
application security
Resources
Resources
Java 2 Network Security
Marco Pistoia, et al, Prentice Hall, 1999, ISBN 0-13-015592-6
Java and Internet Security
Shrader, Rich, Nadalin, IUniverse, 2000, ISBN 0-595-13500-5
http://www.research.ibm.com/compsci/security/javasec/ http://java.sun.com/security
http://java.sun.com/products/jaas
http://www.ietf.org/rfc/rfc1510.txt, Kerberos V5 http://www.ietf.org/rfc/rfc2743.txt, GSS V2
Java is a trademark and Java 2 is a registered trademark of Sun Microsystems Inc.
Backup Materials
Java 2 Standard
Edition Security:
Review
CodeSource
CodeSource
Combination of a set of Signers
(certificates) and a code base
URL
Certificate 1
Certificate 2 Code Base
URL
CodeSource
...
Policy
Policy
A
Permission
is an access right
to a protected resource
In Java 2, Permissions are
stored in the
Policy
object
The reference implementation
is file based
Sample Java 2 Policy
Sample Java 2 Policy
grant
entries
Describe Permissions
granted to CodeSources
An entry may contain one or
more Permissions
grant signedBy "mykey", codeBase "file:E:/mydir/app/*" {
permission java.lang.RuntimePermission "queuePrintJob";
ProtectionDomain
ProtectionDomain
A
ProtectionDomain
contains:
A CodeSource
The Permissions granted to the
CodeSource
SecureClassLoader assigns a
ProtectionDomain to each loaded class
Classes with different CodeSources belong
to different ProtectionDomains
Certificate 1
Certificate 2 Code Base
URL Permission 1 Permission 1 Permission 2
...
Permission M...
Certificate NClasses, ProtectionDomains &
Classes, ProtectionDomains &
Permissions
Permissions
Each class is assigned to only one
ProtectionDomain
As determined by its CodeSource
Each ProtectionDomain may include
zero or more Permissions
Multiple classes from the same
CodeSource are assigned the same
ProtectionDomain
. . .
/*
Check to see if the calling
code is authorized.
If not, a SecurityException
(AccessControlException) will be
thrown
*/
AccessController.checkPermission(
new RuntimePermission("queuePrintJob"));
Example of Guard on
Example of Guard on
Protected Resource
Protected Resource
O'Reilly Conference on Enterprise Java March 26-29, 2001
import java.security.*; class GetProperty {
public static void main(String[] args) { try {
if (args.length > 0) {
String s = System.getProperty(args[0],"name " + args[0] + " not specified");
System.out.println(args[0] + " property
value is: " + s);
} else {
System.out.println("Property name
required");
} }
catch(Exception e){
System.err.println("Caught exception " + e.toString());
} } }
The GetProperty Example
Each thread in the JVM contains a
number of
stack frames
Each stack frame contains the
method instance variables for a
method called in the current thread
A
thread of execution
may:
Occur completely within a single
protection domain
May involve application
ProtectionDomain(s) and the
system ProtectionDomain
Threads of Execution in Java
Check of Current Thread
Check of Current Thread
1. AccessController is in the system ProtectionDomain – Permission is implicitly granted
Proceed to the next frame on the thread stack
2. SecurityManager is in the system ProtectionDomain – Permission is implicitly granted
Proceed to the next frame on the thread stack
3. System is in the system ProtectionDomain – Permission is implicitly granted
Proceed to the next frame on the thread stack
4. GetProperty is in the application domain – Is the permission granted?
If yes, then proceed to the next frame on the thread stack If no, throw a SecurityException
java.security.AccessController.checkPermission() java.lang.SecurityManager.checkPropertyAccess()
GetProperty.main() java.lang.System.getProperty()
Calling hierarchy checkPermission()
Determining the Permission
Determining the Permission
Set of a Thread
Set of a Thread
The Permission set of a thread is the intersection of all ProtectionDomains traversed by the execution thread ProtectionDomain 1 ProtectionDomain 2 ProtectionDomain K
I
K K i M j K i j iPerm
, , 2 , 1 , , 2 , 1 , = =P1
ProtectionDomain for Class1 = { P1, P3 }
P3
Authorization - Permissions
Authorization - Permissions
Class1.methodA calls Class2.methodB
ProtectionDomain for Class2 = { P2, P3 }
P2
P3
P3
checkPermission(P1) fails checkPermission(P2) fails checkPermission(P3) succeedsAuthorization - Permissions
Authorization - Permissions
Class1.methodA calls Class2.methodB Calls AccessController.doPrivileged() Class2.methodCP1
P3
P2
ProtectionDomain for Class1 = { P1, P3 }
ProtectionDomain for Class2 = { P2, P3 }
checkPermission(P1) fails
Authorization - Permissions
Authorization - Permissions
Class1.methodA calls doPrivileged(AccessControlContext({P3,P4})) calls Class2.methodBP1
P3
P2
P4
AccessControlContext = {P3, P4} ProtectionDomain for Class1 = { P1, P3 }ProtectionDomain for Class2 = { P2, P3 }
checkPermission(P3) succeeds
Lexical Scoping of
Lexical Scoping of
Privilege Modification
Privilege Modification
How privileged code works
Why it is necessary
Algorithm for run-time access control
Why Privileged Code?
Why Privileged Code?
Application System utility An application is not allowed to access font files The system utility to display a document must obtain those fonts on behalf of the user The application is temporarily enabled to access the font files
The Privileged Code
The Privileged Code
Mechanism
Mechanism
doPrivileged() annotates the stack frame
AccessController.checkPermission() stops Permission testing at this stack frame
ProtectionDomain for the class and all the classes that it calls are checked
ProtectionDomain of its callers are not checked
Caller class – Permission testing not performed Class called – Permission testing performed Caller class – Permission testing not performed
Class called – Permission testing performed testing Class called – Permission testing performed
Example Privileged Code
Example Privileged Code
Must use
java.security.PrivilegedAction
interface
The run() method contains code needing
privilege
AccessController.doPrivileged()
Takes
PrivilegedAction
object argument
Invokes its
run()
method
Example - Anonymous
Example - Anonymous
Inner Class
Inner Class
someMethod() {// some normal code here...
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
// privileged code goes here, for example:
System.loadLibrary("awt");
return null; // nothing to return
} }
);
For each class on the thread stack: Get the class's ProtectionDomain If the stack frame is annotated by a doPrivileged(),
Exit the loop
If the last stack frame checked is not annotated with by a doPrivileged(),
Add the ProtectionDomains inherited by the current thread when the current thread was instantiated
AccessController Algorithm -
AccessController Algorithm -
Stage 1
Stage 1
If no ProtectionDomains from step1,
Return (only fully trusted code is running)
For each unique ProtectionDomain P obtained in
stage 1,
Call P's implies() method with the Permission
Does P imply the Permission being checked?
If no, Throw an exception Else, Continue
AccessController Algorithm -
AccessController Algorithm -
Stage 2
Stage 2
Check each ProtectionDomain to see whether
it contains the Permission being checked
Policy based
Uses a "principal" extension
Lexically scoped
Subject.doAs() & doAsPrivileged take a
PrivilegedAction /
PrivilegedExceptionAction as an
argument
But, no doPrivileged() mark
Authorization algorithm unmodified
JAAS / J2SE Authorization
JAAS / J2SE Authorization
Relationship
Sample JAAS Policy
Sample JAAS Policy
Consists of
grant
entries
Describe Permissions granted to
CodeSources
and
Principals
Each entry may contain one or
more Permissions
grant signedBy "mykey", codeBase "file:E:/Solutions/app/*"
principal com.esite.WebPrincipal "George" {
permission java.lang.RuntimePermission "queuePrintJob"; };
Sample JAAS Policy -
Sample JAAS Policy -
Roles
Roles
"Roles" can be assigned to
Subjects
Authorization performed based
on "Role" assigned to subject
grant signedBy "mykey", codeBase "file:E:/Solutions/app/*"
principal com.eDMV.MethodRole "DMVSupervisor" {
permission com.ebank.AccountAccess "CloseAccount"; };
Example doAs()
Example doAs()
Lexically scoped Subject
. . .
// Authenticate user & build a Subject wUser
. . .
// Switch to the authenticated user
Subject.doAs(wUser, new PrivilegedAction() { public Object Run(){
// Work to be done as wUser requiring
// the addition of the user's privileges return processUserRequest();
}
} // end of PrivilegedAction );
Subject.doAs() Effect
Subject.doAs() Effect
Extends the effective
ProtectionDomains of methods
called after the Subject.doAs()
call
Example scenario
Example scenario
Thread / Class
Permissions
Effective Thread
Permission
Class 1
Class 2
Class 3
Class 4
{ P1, P2 }
{ P1, P3 }
{ P2 }
{ P1, P5 }
{ P1, P2 }
{ P1 }
checkPermission(P1)
fails
P
3
P
c2 3
P
c3 3
P
= { }
{ }
{ }
Augmented with doAs()
Augmented with doAs()
Thread / Class
Permissions
Effective Thread
Permission
Class 1
Class 2
Class 3
Class 4
{ P1, P2 }
{ P1, P3 }
{ P2,
P1, P4
}
{ P1, P5,
P4
}
{ P1, P2 }
{ P1 }
doAs(X)
{
P1, P4
}
{
P1
}
checkPermission(P1)
succeeds!
{
P1
}
P
c13
P
c23
(P
c3U P
X)
3
(P
c4U P
X) = { P1 }
Another doAs() scenario
Another doAs() scenario
Thread / Class
Permissions
Effective Thread
Permission
Class 1
Class 2
{ P1, P2 }
{ P1,
P2, P3
}
{ P1, P2 }
doAs(X)
{
P2, P3
}
{ P1,
P2
}
checkPermission(P2)
succeeds!
P
3
(P
U P
) = { P1, P2 }
Another doAs() scenario
Another doAs() scenario
(con't)
(con't)
Thread / Class
Permissions
Effective Thread
Permission
Class 1
Class 2
{ P1, P2 }
{ P1,
P2, P3
}
{ P1, P2 }
doAs(X)
{
P2, P3
}
{ P1,
P2
}
Class 2 { P1,
P3
}
doAs(Y)
{
P1, P3
}
{ P1 }
checkPermission(P2)
fails!
P
c13
(P
c2
UP
X
)
3
(P
c2
UP
Y
)={P1}
Summary
Summary
Subject.doAs() extends the
ProtectionDomains of all classes / methods
which the PrivilegedAction object calls
The basic CodeSource authorization
algorithm is unmodified
Subsequent Subject.doAs() calls replace
the Subject in the authorization algorithm
Java is a trademark and Java 2 is a registered trademark of Sun Microsystems Inc.
JAAS
and
EJBs
EJB Roles
EJB Roles
Enterprise Bean Provider Application Assembler Deployer
System Administrator EJB Server Provider EJB Container Provider
Development/Deployment
Development/Deployment
Process
Process
Enterprise Bean
Providers
Application
Assembler
Deployer
System
Administrator
JAAS->EJB security
JAAS->EJB security
Containers implement security
JAAS is a reasonable building block EJB security built around "roles" JAAS built around "Principal"s Mapping required/possible
Identity (Principal) Mapping
Front-end authenticated principal can be mapped to principal required by back-end systems
Credential Mapping
Used when application server’s and backend support different authentication domains
i.e. PKI to Kerberos
Principal to EJB security role mapping
JAAS->EJB security (cont)
Exploiting J2SE Security
Exploiting J2SE Security
(1/4)
(1/4)
How can J2SE mechanisms perform
container-based authentication / authorization ? JAAS login modules perform principal
authentication
JAAS principal created
Maps authenticated principal to EJB role(s) EJB method authorization is based on
Example: Role as principals :
Mapping of principal to "role principals" happens in the JAAS login module
isCallerInRole() looks for the appropriate EJB role principal in the in the current thread
Typically, does the current caller have permission for this method?
Method dispatch authorization tests check, via checkPermission(), the corresponding
MethodPermission JAAS-like Syntax: grant MethodPermission(ejb.account.withdraw) to RolePrincipal(customer) grant MethodPermission(ejb.loan.borrow) to RolePrincipal(customer)
Exploiting J2SE Security
Exploiting J2SE Security
Exploiting J2SE Security
(3/4)
(3/4)
Example: Role as Permissions:
Given principal-to-roles map, assign permissions for all roles to this principal
Mapping takes place "statically" in the authorization policy definition
Potential problems:
Treats a role both as a principal and a permission
Is dependent on a mapping from method permission from a role permission
JAAS-like Syntax
grant RolePermission(customer) to sam
grant MethodPermission(ejb.account.withdraw) to RolePrincipal(customer)
Exploiting J2SE Security
Exploiting J2SE Security
(4/4)
(4/4)
Example: Role as collection of permissions and credential
Role is granted a collection of permissions
isCallerInRole() done by checking if caller has access to appropriate RolePermission
collection
Individual method permission test performed by searching the Role permission collections,
granted to the subject, for a method permissions that matches desired operation
JAAS-like Syntax
define RolePermission (customer) as {
MethodPermission(ejb.account.withdraw) MethodPermission(ejb.loan.borrow)
... }