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 Permission
s
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 LoginContext
s
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
LoginContext
s 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 MoriaLoginModule
s
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
Principal
s.
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.