How to Use JAAS? [Terms to be Noticed] 1. LoginModule : the module to check user login 2. CallbackHandler : used to collect user login information 3. Principal : role 4. Permission : a certain kind of permission 5. Subject : obtained from LoginContext; contain Permission settings [Configuration File Syntax] 1. JAAS LoginModule configure file : ============================================================== SimpleLoginContext { test.SimpleLoginModule required resourceIdMapper=test.MappedResourceIdMapperImpl BASEDN="cn=users,DC=leopard,DC=iis,DC=sinica,DC=edu,DC=tw" IDATTRNAME=cn; }; ============================================================== 2. General Policy File : ============================================================== grant { permission java.lang.RuntimePermission "stopThread"; // allows anyone to listen on un-privileged ports permission java.net.SocketPermission "localhost:1024-", "listen"; // "standard" properies that can be read by anyone permission java.util.PropertyPermission "java.version", "read"; permission java.util.PropertyPermission "java.vendor", "read"; permission java.util.PropertyPermission "java.vendor.url", "read"; }; grant codeBase "file:D:/jdk/projects/JAASwithDS/unsecured/-" { permission java.security.AllPermission; }; grant codeBase "file:D:/jdk/projects/JAASwithDS/lib/-" { permission java.security.AllPermission; }; grant codeBase "file:D:/jdk/projects/JAASwithDS/secured/-" { permission javax.security.auth.AuthPermission "createLoginContext.SimpleLoginContext"; permission javax.security.auth.AuthPermission "doAsPrivileged"; permission java.io.FilePermission "foo.txt", "write"; permission java.io.FilePermission "<>", "read"; }; ============================================================== 3. Principal Related Policy File : ============================================================== grant Principal test.SimplePrincipal "lendle" { permission java.io.FilePermission "test.txt", "write"; }; ============================================================== [Related Command-line Settings] 1. -Djava.security.manager : enable default SecurityManager, this will use default policy file located in ${JAVA_HOME}/[jre]/lib/security/java.policy 2. -Djava.security.auth.login.config : point to the JAAS LoginModule configure file 3. -Djava.security.auth.policy : point to the Principal-only policy file (note: append the pointed file to the current policy files list; to use the pointed file as the only policy file, use == instead of =) 4. -Djava.security.policy : point to the general policy file, this can also be achieved by modifying the java.security file [How to Run?] 1. configure (maybe custom Permission classes should be developed at first) 2. get SecurityManager properly (*) 3. create a LoginContext and provide a CallbackHandler 4. do login, a Subject instance will be returned 5. use Subject.doAsPrivileged() to perform privileged actions (e.x. SecurityManager.checkPermission()) [Notes and Several Runtime Scenarios] 1. if -Djava.security.manager is used : the main class, the LoginModules, and all other classes are subject to system policy file constraint this is less flexible 2. if -Djava.security.manager is not used : create a new SecurityManager in main class, the newly created SecurityManager will also load all policy files specified, therefore, if System.setSecurityManager() is called, the case is identical with case 1. However, if System.setSecurityManager() is not called, all permission settings will only be enabled when SecurityManager.checkPermission() is called 3. before create new SecurityManager instance : System.getSecurityManager() should always be called in advance to see if there is pre-installed SecurityManager already 4. Custom Permission : when implementing custom Permission classes, generally getActions() and implies() and newPermissionCollection() must be implemented, however, must be careful not add permission instance that is under test into the collection [Examples] 1. In this example, only use new SecurityManager to check Principal-related permissions : ====================================================================================== command line : -Djava.security.auth.login.config=${res}/jaas.config -Djava.security.auth.policy=${res}/jaas.policy LoginModule configuration : SimpleLoginContext { test.SimpleLoginModule required resourceIdMapper=test.MappedResourceIdMapperImpl BASEDN="cn=users,DC=leopard,DC=iis,DC=sinica,DC=edu,DC=tw" IDATTRNAME=cn; }; Principal policy file : grant Principal test.SimplePrincipal "AAA" { permission java.io.FilePermission "test.txt", "write"; }; source code : SecurityManager sm=System.getSecurityManager(); if(sm==null) { sm=new SecurityManager(); } final SecurityManager _sm=sm; LoginContext ctx = new LoginContext("SimpleLoginContext", new CallbackHandler() { public void handle(Callback[] callbacks) { try { BufferedReader input = new BufferedReader( new InputStreamReader(System.in)); for (int i = 0; i < callbacks.length; i++) { if (callbacks[i] instanceof NameCallback) { NameCallback nc = (NameCallback) (callbacks[i]); System.out.println(nc.getPrompt()); nc.setName(input.readLine()); } else { PasswordCallback pc = (PasswordCallback) (callbacks[i]); System.out.println(pc.getPrompt()); pc.setPassword(input.readLine().toCharArray()); } } input.close(); } catch (Exception e) {} } }); ctx.login(); Subject subject = ctx.getSubject(); Subject.doAsPrivileged(subject, new PrivilegedAction(){ public Object run() { _sm.checkPermission(new java.io.FilePermission("test.txt","write")); return null; } }, null); ======================================================================================