Subject
The agent that is going to be authenticated.
Principal
Represents an identity of the agent. They can be thought of as attributes. One agents may have many principals. Permissions are given to principals.
Credential
Security-related attributes, which may be represented by any class, and are either private or public.
LoginContext
Provides the basic methods used to authenticate subjects and a way to develop an application independent of the underlying authentication technology.
LoginModule
Implements an authentication technology.
CallbackHandler
A LoginModule uses the CallbackHandler both to gather input from users (like username and password) and to supply information to users.
Configuration file
Contains which LoginModules and whether they are "required, "requisite", "sufficient" or optional. Options are also specified.
Policy
Reads the permissions from the policy file.
Permission
A permission has a type, a name and possibly actions and are given to code or principals in the policy file.
SecurityManager
Provides the permission checks. Note that you own Permissions
are not checked automatically, but you have to add this in your application:
SecurityManager sm = System.getSecurityManager()
if(sm!=0){
sm.checkPermission(new MyPermission(name));
}
Policy file
Here you store the permissions. It does not have to be a file, you may want to store the permissions in a database.
no.feide.mellon.jaas.loginmodules
The only LoginModule is the MoriaLoginModule, which
uses no.feide.mellon.v2_1.Moria for authentication.
no.feide.mellon.jaas.principals
The main Principal implementation is the MoriaPrincipal.
To enable use of wildcards two other principal-types is implemented as well,
EntitlementPrincipal and ScopedAffiliationPrincipal.
no.feide.mellon.jaas.callbackhandlers
It contains two callbackHandlers, CommandlineCallbackHandler that
prompts the user for username and password and PassiveCallbackHandler.
no.feide.mellon.jaas.loginutility
The Login class and the MoriaAction class will hide
the use of JAAS completely from the application.
no.feide.mellon.jaas.application
It contains one class Demo, a small sample application.
This is how you run the code:
java -Djava.security.auth.login.config==jaas.config \
-Djava.security.auth.manager \
-Djava.security.policy==jaas.policy \
Login \
Demo \
[args]
This means you run the Login class and that the application
that is going to use JAAS, Demo, is the first argument.
The next arguments are arguments for the main method in
Demo.
Double "=", "==", means that this is the only configuration- and policy-file that
is to be considered. Note that you will have to write or modify jaas.config
and jaas.policy. Examples are provided below.
jaas.config
no.feide.mellon.jaas.application.Demo{
no.feide.mellon.jaas.loginmodules.MoriaLoginModule required
debug=true
endpoint="http://localhost:8080/moria/v2_1/Authentication"
service_username="demo_service"
service_password="demo_service";
};
jaas.policy
//This is only an example. It cannot be used without modifications.
//"standard" properties that can be read by anyone
grant {
permission java.util.PropertyPermission "java.version", "read";
permission java.util.PropertyPermission "java.vendor", "read";
permission java.util.PropertyPermission "java.vendor.url", "read";
permission java.util.PropertyPermission "java.class.version", "read";
permission java.util.PropertyPermission "os.name", "read";
permission java.util.PropertyPermission "os.version", "read";
permission java.util.PropertyPermission "os.arch", "read";
permission java.util.PropertyPermission "file.separator", "read";
permission java.util.PropertyPermission "path.separator", "read";
permission java.util.PropertyPermission "line.separator", "read";
permission java.util.PropertyPermission "java.specification.version", "read";
permission java.util.PropertyPermission "java.specification.vendor", "read";
permission java.util.PropertyPermission "java.specification.name", "read";
permission java.util.PropertyPermission "java.vm.specification.version", "read";
permission java.util.PropertyPermission "java.vm.specification.vendor", "read";
permission java.util.PropertyPermission "java.vm.specification.name", "read";
permission java.util.PropertyPermission "java.vm.version", "read";
permission java.util.PropertyPermission "java.vm.vendor", "read";
permission java.util.PropertyPermission "java.vm.name", "read";
};
grant codebase "file:D:/Feide/-"{
permission java.security.AllPermission;
};
grant codebase "file:D:/JavaLibraries/-"{
permission java.security.AllPermission;
};
grant codebase "file:D:/win/eclipse/workspace/JAAS/-"{
permission javax.security.auth.AuthPermission "createLoginContext";
permission javax.security.auth.AuthPermission "modifyPrincipals";
permission javax.security.auth.AuthPermission "modifyPublicCredentials";
permission javax.security.auth.AuthPermission "modifyPrivateCredentials";
permission javax.security.auth.AuthPermission "doAsPrivileged";
permission java.util.PropertyPermission "axis.xml.reuseParsers", "read";
permission java.util.PropertyPermission "axis.attachments.implementation", "read";
permission java.util.PropertyPermission "java.protocol.handler.pkgs", "read, write";
permission java.util.PropertyPermission "axis.byteBuffer.cacheIncrement", "read";
permission java.util.PropertyPermission "axis.byteBuffer.residentMaxSize", "read";
permission java.util.PropertyPermission "axis.byteBuffer.workBufferSize", "read";
permission java.util.PropertyPermission "axis.byteBuffer.backing", "read";
permission java.util.PropertyPermission "axis.doAutoTypes", "read";
permission java.util.PropertyPermission "http.nonProxyHosts", "read";
permission java.util.PropertyPermission "http.proxyUser", "read";
permission java.util.PropertyPermission "http.proxyHost", "read";
permission java.net.SocketPermission "localhost", "resolve";
permission java.net.SocketPermission "127.0.0.1:8080", "connect,resolve";
permission java.io.FilePermission "D:\\JavaLibraries\\axis-bin-1_2_1\\axis-1_2_1\\lib\\-", "read";
permission java.io.FilePermission "D:\\win\\eclipse\\workspace\\Moria\\-", "read";
permission java.io.FilePermission "D:\\win\\eclipse\\workspace\\JAAS\\-", "read,write";
};
grant Principal jaas.principals.MoriaPrincipal "eduPersonEntitlement:urn:mace:feide.no:gullgraverskolen.no:forsteklondike"{
permission java.util.PropertyPermission "user.home", "read";
};
grant Principal jaas.principals.EntitlementPrincipal "*:*:*:gullgraverskolen.no:*"{
permission java.util.PropertyPermission "java.home", "read";
};
The configuration file jaas.config and the policy file
jaas.policy can be specified in the java.policy
and java.security files located in the directory
lib/security/ in the java runtime folder. The security Manager
can be constructed in the Login class (before
the LoginContext is created). This is done like this:
System.setSecurityManager(new SecurityManager())
The no.feide.mellon.jaas.loginutility.Login class initiates a
LoginContext and calls the LoginContexts
login method. The name in the loginconfiguration,
jaas.config, is the same as the name of the application that is
going to use this JAAS-module and the CallbakHandler used is the
no.feide.mellon.jaas.calbackhandlers.CommandlineCallbackHandler.
You get three login attempts (specified in the Login class).
The only LoginModule used is
no.feid.mellon.jaas.loginmodules.MoriaLoginModule, and it is
required as specified in jaas.config. When the
LoginContexts login method is called the
LoginContext initiates the MoriaLoginModule and
calls its login method.
The MoriaLoginModule uses the given CallbackHandler to
ask for username and password. The login method in
MoriaLoginModule calls the MoriaLoginModules
validate method which constructs a no.feide.mellon.v2_1.Moria
object and calls its directNonInteractiveAuthentication method.
The username and password is checked and the attributes specified in the
MoriaLoginModules static variable ATTRIBUTE_NAMES are
returned. For each of the Attributes returned a new
no.feide.mellon.jaas.principals.MoriaPrincipal is constructed. The
commit method in MoriaLoginModule saves this
principals in the Subject object returned to the LoginContext
if the login and commit method of the
MoriaLoginModule both return true.
The Login class retrieves the Subject from the
LoginContext and tries to run the
no.feide.mellon.jaas.loginutility.MoriaAction as this subject.
The MoriaAction starts the application, Demo. This
means that the application is run as the authenticated subject.
When run with the default SecurityManager, all the standard permissions
will be checked. The application is run as the subject, so what the application can
do is restricted by the subject's permissions. The permission are granted to
principals and/or code and specified in jaas.policy.
You can read more about policy files here:
"Default Policy Implementation and Policy File Syntax"
I have used the default Policy implementation,
com.sun.security.auth.PolicyFile. This means I have used the standard
described in the link above to write the jaas.policy file.
During login attributes are stored as MoriaPrincipals in the authenticated
subject. The string representation of a MoriaPrincipal is
"attributeName:attributeValue". This is used in the policy file.
MoriaPrincipals cannot contain wildcards. To enable use of wildcards
in the policy file for specific attributes, new principal types that extend
MoriaPrincipal and implements the
com.sun.security.auth.PrincipalComparator are implemented. These
principals are EntitlementPrincipal and ScopedAffiliationPrincipal
and they are only used in the policy file.
You can use EntitlementPrincipal when you want to use wildcards in the
attribute value of eduPersonEntitlement. The eduPersonEntitlement
values have this format: a:b:c:d, where the number of ":" may vary. You can replace
any of the parts a,b,c etc. with a wildcard. The parts a,b,c etc. cannot contain any
":". For to values to mach, the number of ":" must be the same.
You can use ScopedAffiliationPrincipal if you want to use wildcards
in the attribute value of eduPersonScopedAffiliation. The
eduPersonScopedAffiliation values have this format:
"affiliation@securityDomain". The affiliation can be replaced by a wildcard, but
the security domain cannot.
To use this module for your own application, you might have to change the
Login class. When the LoginContext is created you can
choose another CallbackHandler. And you can change/remove the part
where you get three login attempts.
You have to change which FEIDE attributes you want to retrieve when you authenticate
against Moria. They are specified in the MoriaLoginModule,
but you might want to put in in a configuration file.
You might also need another CallbackHandler and additional special
Principals.
If you do not want to follow the policy file standard, but want to use xml or something
else, you can make your own. Then you will have to implement a new Policy
class extending the com.sun.security.auth.PolicyFile class or implementing
the javax.security.auth.Policy interface.
If you need any custom permissions, you have to implement them exteding
java.security.BasicPermission or java.security.Permission.
The jaas.config file and jaas.policy need to be written.