SampleServer.java
import org.ietf.jgss.*; import java.io.*; import java.net.Socket; import java.net.ServerSocket; /** * A sample server application that uses JGSS to do mutual authentication * with a client using Kerberos as the underlying mechanism. It then * exchanges data securely with the client. * * Every message exchanged with the client includes a 4-byte application- * level header that contains the big-endian integer value for the number * of bytes that will follow as part of the JGSS token. * * The protocol is: * 1. Context establishment loop: * a. client sends init sec context token to server * b. server sends accept sec context token to client * .... * 2. client sends a wrap token to the server. * 3. server sends a mic token to the client for the application * message that was contained in the wrap token. */ public class SampleServer { public static void main(String[] args) throws IOException, GSSException { // Obtain the command-line arguments and parse the port number if (args.length != 1) { System.err.println("Usage: java <options> Login SampleServer <localPort>"); System.exit(-1); } int localPort = Integer.parseInt(args[0]); ServerSocket ss = new ServerSocket(localPort); GSSManager manager = GSSManager.getInstance(); while (true) { System.out.println("Waiting for incoming connection..."); Socket socket = ss.accept(); DataInputStream inStream = new DataInputStream(socket.getInputStream()); DataOutputStream outStream = new DataOutputStream(socket.getOutputStream()); System.out.println("Got connection from client " + socket.getInetAddress()); /* * Create a GSSContext to receive the incoming request * from the client. Use null for the server credentials * passed in. This tells the underlying mechanism * to use whatever credentials it has available that * can be used to accept this connection. */ GSSContext context = manager.createContext((GSSCredential)null); // Do the context eastablishment loop byte[] token = null; while (!context.isEstablished()) { token = new byte[inStream.readInt()]; System.out.println("Will read input token of size " + token.length + " for processing by acceptSecContext"); inStream.readFully(token); token = context.acceptSecContext(token, 0, token.length); // Send a token to the peer if one was generated by // acceptSecContext if (token != null) { System.out.println("Will send token of size " + token.length + " from acceptSecContext."); outStream.writeInt(token.length); outStream.write(token); outStream.flush(); } } System.out.print("Context Established! "); System.out.println("Client is " + context.getSrcName()); System.out.println("Server is " + context.getTargName()); /* * If mutual authentication did not take place, then * only the client was authenticated to the * server. Otherwise, both client and server were * authenticated to each other. */ if (context.getMutualAuthState()) System.out.println("Mutual authentication took place!"); /* * Create a MessageProp which unwrap will use to return * information such as the Quality-of-Protection that was * applied to the wrapped token, whether or not it was * encrypted, etc. Since the initial MessageProp values * are ignored, just set them to the defaults of 0 and false. */ MessageProp prop = new MessageProp(0, false); /* * Read the token. This uses the same token byte array * as that used during context establishment. */ token = new byte[inStream.readInt()]; System.out.println("Will read token of size " + token.length); inStream.readFully(token); byte[] bytes = context.unwrap(token, 0, token.length, prop); String str = new String(bytes); System.out.println("Received data \"" + str + "\" of length " + str.length()); System.out.println("Confidentiality applied: " + prop.getPrivacy()); /* * Now generate a MIC and send it to the client. This is * just for illustration purposes. The integrity of the * incoming wrapped message is guaranteed irrespective of * the confidentiality (encryption) that was used. */ /* * First reset the QOP of the MessageProp to 0 * to ensure the default Quality-of-Protection * is applied. */ prop.setQOP(0); token = context.getMIC(bytes, 0, bytes.length, prop); System.out.println("Will send MIC token of size " + token.length); outStream.writeInt(token.length); outStream.write(token); outStream.flush(); System.out.println("Closing connection with client " + socket.getInetAddress()); context.dispose(); socket.close(); } } }
bcsLogin.conf
/** * Login Configuration for JAAS. */ com.sun.security.jgss.initiate { com.sun.security.auth.module.Krb5LoginModule required; }; com.sun.security.jgss.accept { com.sun.security.auth.module.Krb5LoginModule required storeKey=true; };
SampleClient.java
import org.ietf.jgss.*; import java.net.Socket; import java.io.IOException; import java.io.DataInputStream; import java.io.DataOutputStream; /** * A sample client application that uses JGSS to do mutual authentication * with a server using Kerberos as the underlying mechanism. It then * exchanges data securely with the server. * * Every message sent to the server includes a 4-byte application-level * header that contains the big-endian integer value for the number * of bytes that will follow as part of the JGSS token. * * The protocol is: * 1. Context establishment loop: * a. client sends init sec context token to server * b. server sends accept sec context token to client * .... * 2. client sends a wrap token to the server. * 3. server sends a MIC token to the client for the application * message that was contained in the wrap token. */ public class SampleClient { public static void main(String[] args) throws IOException, GSSException { // Obtain the command-line arguments and parse the port number if (args.length < 3) { System.err.println("Usage: java <options> Login SampleClient " + " <server> <hostName> <port>"); System.exit(-1); } String server = args[0]; String hostName = args[1]; int port = Integer.parseInt(args[2]); Socket socket = new Socket(hostName, port); DataInputStream inStream = new DataInputStream(socket.getInputStream()); DataOutputStream outStream = new DataOutputStream(socket.getOutputStream()); System.out.println("Connected to server " + socket.getInetAddress()); /* * This Oid is used to represent the Kerberos version 5 GSS-API * mechanism. It is defined in RFC 1964. We will use this Oid * whenever we need to indicate to the GSS-API that it must * use Kerberos for some purpose. */ Oid krb5Oid = new Oid("1.2.840.113554.1.2.2"); GSSManager manager = GSSManager.getInstance(); /* * Create a GSSName out of the server's name. The null * indicates that this application does not wish to make * any claims about the syntax of this name and that the * underlying mechanism should try to parse it as per whatever * default syntax it chooses. */ GSSName serverName = manager.createName(server, null); /* * Create a GSSContext for mutual authentication with the * server. * - serverName is the GSSName that represents the server. * - krb5Oid is the Oid that represents the mechanism to * use. The client chooses the mechanism to use. * - null is passed in for client credentials * - DEFAULT_LIFETIME lets the mechanism decide how long the * context can remain valid. * Note: Passing in null for the credentials asks GSS-API to * use the default credentials. This means that the mechanism * will look among the credentials stored in the current Subject * to find the right kind of credentials that it needs. */ GSSContext context = manager.createContext(serverName, krb5Oid, null, GSSContext.DEFAULT_LIFETIME); // Set the desired optional features on the context. The client // chooses these options. context.requestMutualAuth(true); // Mutual authentication context.requestConf(true); // Will use confidentiality later context.requestInteg(true); // Will use integrity later // Do the context eastablishment loop byte[] token = new byte[0]; while (!context.isEstablished()) { // token is ignored on the first call token = context.initSecContext(token, 0, token.length); // Send a token to the server if one was generated by // initSecContext if (token != null) { System.out.println("Will send token of size " + token.length + " from initSecContext."); outStream.writeInt(token.length); outStream.write(token); outStream.flush(); } // If the client is done with context establishment // then there will be no more tokens to read in this loop if (!context.isEstablished()) { token = new byte[inStream.readInt()]; System.out.println("Will read input token of size " + token.length + " for processing by initSecContext"); inStream.readFully(token); } } System.out.println("Context Established! "); System.out.println("Client is " + context.getSrcName()); System.out.println("Server is " + context.getTargName()); /* * If mutual authentication did not take place, then only the * client was authenticated to the server. Otherwise, both * client and server were authenticated to each other. */ if (context.getMutualAuthState()) System.out.println("Mutual authentication took place!"); byte[] messageBytes = "Hello There!\0".getBytes(); /* * The first MessageProp argument is 0 to request * the default Quality-of-Protection. * The second argument is true to request * privacy (encryption of the message). */ MessageProp prop = new MessageProp(0, true); /* * Encrypt the data and send it across. Integrity protection * is always applied, irrespective of confidentiality * (i.e., encryption). * You can use the same token (byte array) as that used when * establishing the context. */ token = context.wrap(messageBytes, 0, messageBytes.length, prop); System.out.println("Will send wrap token of size " + token.length); outStream.writeInt(token.length); outStream.write(token); outStream.flush(); /* * Now we will allow the server to decrypt the message, * calculate a MIC on the decrypted message and send it back * to us for verification. This is unnecessary, but done here * for illustration. */ token = new byte[inStream.readInt()]; System.out.println("Will read token of size " + token.length); inStream.readFully(token); context.verifyMIC(token, 0, token.length, messageBytes, 0, messageBytes.length, prop); System.out.println("Verified received MIC for message."); System.out.println("Exiting..."); context.dispose(); socket.close(); } }
JaasAcn.java
import javax.security.auth.*; import javax.security.auth.callback.*; import javax.security.auth.login.*; import com.sun.security.auth.callback.TextCallbackHandler; /** * This JaasAcn application attempts to authenticate a user * and reports whether or not the authentication was successful. */ public class JaasAcn { public static void main(String[] args) { // Obtain a LoginContext, needed for authentication. Tell it // to use the LoginModule implementation specified by the // entry named "JaasSample" in the JAAS login configuration // file and to also use the specified CallbackHandler. LoginContext lc = null; try { lc = new LoginContext("JaasSample", new TextCallbackHandler()); } catch (LoginException le) { System.err.println("Cannot create LoginContext. " + le.getMessage()); System.exit(-1); } catch (SecurityException se) { System.err.println("Cannot create LoginContext. " + se.getMessage()); System.exit(-1); } try { // attempt authentication lc.login(); } catch (LoginException le) { System.err.println("Authentication failed:"); System.err.println(" " + le.getMessage()); System.exit(-1); } System.out.println("Authentication succeeded!"); } }
jass.conf
/** Login Configuration for the JaasAcn and ** JaasAzn Applications **/ JaasSample { com.sun.security.auth.module.Krb5LoginModule required; };
jassacn.policy
/** Java Access Control Policy for the JaasAcn Application **/ grant codebase "file:./JaasAcn.jar" { permission javax.security.auth.AuthPermission "createLoginContext.JaasSample"; };
JaasAzn.java
import javax.security.auth.Subject; import javax.security.auth.callback.*; import javax.security.auth.login.*; import com.sun.security.auth.callback.TextCallbackHandler; import java.security.PrivilegedAction; /** * This JaasAzn application attempts to authenticate a user * and reports whether or not the authentication was successful. * If successful, it then sets up subsequent execution of * code in the run method of the SampleAction class such that * access control checks for security-sensitive operations will be * based on the user running the code. */ public class JaasAzn { public static void main(String[] args) { // Obtain a LoginContext, needed for authentication. Tell it // to use the LoginModule implementation specified by the // entry named "JaasSample" in the JAAS login configuration // file and to also use the specified CallbackHandler. LoginContext lc = null; try { lc = new LoginContext("JaasSample", new TextCallbackHandler()); } catch (LoginException le) { System.err.println("Cannot create LoginContext. " + le.getMessage()); System.exit(-1); } catch (SecurityException se) { System.err.println("Cannot create LoginContext. " + se.getMessage()); System.exit(-1); } try { // attempt authentication lc.login(); } catch (LoginException le) { System.err.println("Authentication failed:"); System.err.println(" " + le.getMessage()); System.exit(-1); } System.out.println("Authentication succeeded!"); // now try to execute the SampleAction as the authenticated Subject Subject mySubject = lc.getSubject(); PrivilegedAction action = new SampleAction(); Subject.doAsPrivileged(mySubject, action, null); } }
SampleAction.java
import java.io.File; import java.security.PrivilegedAction; /** * This is a sample PrivilegedAction implementation, designed to be * used with the JaasAzn class. */ public class SampleAction implements PrivilegedAction { /** * This sample PrivilegedAction performs the following operations: * <ul> * <li> Access the System property <i>java.home</i> * <li> Access the System property <i>user.home</i> * <li> Access the file <i>foo.txt</i> * </ul> * * @return <code>null</code> in all cases. * * @exception SecurityException if the caller does not have permission * to perform any of the operations listed above. */ public Object run() { System.out.println("\nYour java.home property value is: " +System.getProperty("java.home")); System.out.println("\nYour user.home property value is: " +System.getProperty("user.home")); File f = new File("foo.txt"); System.out.print("\nfoo.txt does "); if (!f.exists()) System.out.print("not "); System.out.println("exist in the current working directory."); return null; } }
jassazn.policy
/** Java Access Control Policy for the JaasAzn Application **/ /** Code-Based Access Control Policy for JaasAzn **/ grant codebase "file:./JaasAzn.jar" { permission javax.security.auth.AuthPermission "createLoginContext.JaasSample"; permission javax.security.auth.AuthPermission "doAsPrivileged"; }; /** User-Based Access Control Policy for the SampleAction class ** instantiated by JaasAzn **/ grant codebase "file:./SampleAction.jar", Principal javax.security.auth.kerberos.KerberosPrincipal "your_user_name@your_realm" { permission java.util.PropertyPermission "java.home", "read"; permission java.util.PropertyPermission "user.home", "read"; permission java.io.FilePermission "foo.txt", "read"; };
Login.java
import java.io.*; import java.lang.reflect.*; import java.util.Arrays; import javax.security.auth.callback.*; import javax.security.auth.login.*; import javax.security.auth.Subject; import com.sun.security.auth.callback.TextCallbackHandler; /** * <p> This class authenticates a <code>Subject</code> and then * executes a specified application as that <code>Subject</code>. * To use this class, the java interpreter would typically be invoked as: * * <pre> * % java -Djava.security.manager \ * Login \ * <applicationclass> <applicationClass_args> * </pre> * * <p> <i>applicationClass</i> represents the application to be executed * as the authenticated <code>Subject</code>, * and <i>applicationClass_args</i> are passed as arguments to * <i>applicationClass</i>. * * <p> To perform the authentication, <code>Login</code> uses a * <code>LoginContext</code>. A <code>LoginContext</code> relies on a * <code>Configuration</code> to determine the modules that should be used * to perform the actual authentication. The location of the Configuration * is dependent upon each Configuration implementation. * The default Configuration implementation * (<code>com.sun.security.auth.login.ConfigFile</code>) * allows the Configuration location to be specified (among other ways) * via the <code>java.security.auth.login.config</code> system property. * Therefore, the <code>Login</code> class can also be invoked as: * * <pre> * % java -Djava.security.manager \ * -Djava.security.auth.login.config=<configuration_url> \ * Login \ * <your_application_class> <your_application_class_args> * </pre> */ public class Login { /** * <p> Instantate a <code>LoginContext</code> using the * provided application classname as the index for the login * <code>Configuration</code>. Authenticate the <code>Subject</code> * (three retries are allowed) and invoke * <code>Subject.doAsPrivileged</code> * with the authenticated <code>Subject</code> and a * <code>PrivilegedExceptionAction</code>. * The <code>PrivilegedExceptionAction</code> * loads the provided application class, and then invokes * its public static <code>main</code> method, passing it * the application arguments. * * <p> * * @param args the arguments for <code>Login</code>. The first * argument must be the class name of the application to be * invoked once authentication has completed, and the * subsequent arguments are the arguments to be passed * to that application's public static <code>main</code> method. */ public static void main(String[] args) { // check for the application's main class if (args == null || args.length == 0) { System.err.println("Invalid arguments: " + "Did not provide name of application class."); System.exit(-1); } LoginContext lc = null; try { lc = new LoginContext(args[0], new TextCallbackHandler()); } catch (LoginException le) { System.err.println("Cannot create LoginContext. " + le.getMessage()); System.exit(-1); } catch (SecurityException se) { System.err .println("Cannot create LoginContext. " + se.getMessage()); System.exit(-1); } // the user has 3 attempts to authenticate successfully int i; for (i = 0; i < 3; i++) { try { // attempt authentication lc.login(); // if we return with no exception, authentication succeeded break; } catch (AccountExpiredException aee) { System.err.println("Your account has expired. " + "Please notify your administrator."); System.exit(-1); } catch (CredentialExpiredException cee) { System.err.println("Your credentials have expired."); System.exit(-1); } catch (FailedLoginException fle) { System.err.println("Authentication Failed"); try { Thread.currentThread().sleep(3000); } catch (Exception e) { // ignore } } catch (Exception e) { System.err.println("Unexpected Exception - unable to continue"); e.printStackTrace(); System.exit(-1); } } // did they fail three times? if (i == 3) { System.err.println("Sorry"); System.exit(-1); } // push the subject into the current ACC try { Subject.doAsPrivileged(lc.getSubject(), new MyAction(args), null); } catch (java.security.PrivilegedActionException pae) { pae.printStackTrace(); System.exit(-1); } System.exit(0); } } class MyAction implements java.security.PrivilegedExceptionAction { String[] origArgs; public MyAction(String[] origArgs) { this.origArgs = (String[])origArgs.clone(); } public Object run() throws Exception { // get the ContextClassLoader ClassLoader cl = Thread.currentThread().getContextClassLoader(); try { // get the application class's main method Class c = Class.forName(origArgs[0], true, cl); Class[] PARAMS = { origArgs.getClass() }; java.lang.reflect.Method mainMethod = c.getMethod("main", PARAMS); // invoke the main method with the remaining args String[] appArgs = new String[origArgs.length - 1]; System.arraycopy(origArgs, 1, appArgs, 0, origArgs.length - 1); Object[] args = { appArgs }; mainMethod.invoke(null /*ignored*/, args); } catch (Exception e) { throw new java.security.PrivilegedActionException(e); } // successful completion return null; } }
Sample.java
import java.io.File; public class Sample { /** * This sample class performs the following operations: * <ul> * <li> Access the System property <i>java.home</i> * <li> Access the System property <i>user.home</i> * <li> Access the file <i>foo.txt</i> * </ul> * * @exception SecurityException if the caller does not have permission * to perform any of the operations listed above. */ public static void main (String[] args) throws SecurityException { // If there were any arguments to read, we'd do it here. System.out.println("\nYour java.home property value is: " +System.getProperty("java.home")); System.out.println("\nYour user.home property value is: " +System.getProperty("user.home")); File f = new File("foo.txt"); System.out.print("\nfoo.txt does "); if (!f.exists()) System.out.print("not "); System.out.println("exist in the current working directory."); } }
sample.conf
/** Login Configuration for the Sample Application **/ Sample { com.sun.security.auth.module.Krb5LoginModule required; };
sample.policy
/** Access Control Policy for the Sample Application **/ grant codebase "file:./Login.jar" { permission java.security.AllPermission; }; grant codebase "file:./Sample.jar", Principal javax.security.auth.kerberos.KerberosPrincipal "your_user_name@your_realm" { permission java.util.PropertyPermission "java.home", "read"; permission java.util.PropertyPermission "user.home", "read"; permission java.io.FilePermission "foo.txt", "read"; };
csLogin.conf
/** * Login Configuration for JAAS. */ SampleClient { com.sun.security.auth.module.Krb5LoginModule required; }; SampleServer { com.sun.security.auth.module.Krb5LoginModule required storeKey=true principal="service_principal@your_realm"; };
client.policy
grant CodeBase "file:./Login.jar" { permission java.security.AllPermission; }; grant CodeBase "file:./SampleClient.jar", Principal javax.security.auth.kerberos.KerberosPrincipal "your_user_name@your_realm" { permission java.net.SocketPermission "*", "connect"; permission javax.security.auth.kerberos.ServicePermission "krbtgt/your_realm@your_realm", "initiate"; permission javax.security.auth.kerberos.ServicePermission "service_principal@your_realm", "initiate"; };
server.policy
grant CodeBase "file:./Login.jar" { permission java.security.AllPermission; }; grant CodeBase "file:./SampleServer.jar" Principal javax.security.auth.kerberos.KerberosPrincipal "service_principal@your_realm" { permission java.net.SocketPermission "*", "accept"; permission javax.security.auth.kerberos.ServicePermission "service_principal@your_realm", "accept"; };
SampleServerImp.java
import org.ietf.jgss.*; import java.io.*; import java.net.Socket; import java.net.ServerSocket; import javax.security.auth.Subject; import java.security.PrivilegedAction; /** * A sample server application that uses JGSS to do mutual authentication * with a client using Kerberos as the underlying mechanism. It then * exchanges data securely with the client. * * Every message exchanged with the client includes a 4-byte application- * level header that contains the big-endian integer value for the number * of bytes that will follow as part of the JGSS token. * * The protocol is: * 1. Context establishment loop: * a. client sends init sec context token to server * b. server sends accept sec context token to client * .... * 2. client sends a wrap token to the server. * 3. server sends a mic token to the client for the application * message that was contained in the wrap token. */ public class SampleServerImp { public static void main(String[] args) throws IOException, GSSException { // Obtain the command-line arguments and parse the port number if (args.length != 1) { System.err.println("Usage: java <options> Login SampleServer <localPort>"); System.exit(-1); } int localPort = Integer.parseInt(args[0]); ServerSocket ss = new ServerSocket(localPort); GSSManager manager = GSSManager.getInstance(); while (true) { System.out.println("Waiting for incoming connection..."); Socket socket = ss.accept(); DataInputStream inStream = new DataInputStream(socket.getInputStream()); DataOutputStream outStream = new DataOutputStream(socket.getOutputStream()); System.out.println("Got connection from client " + socket.getInetAddress()); /* * Create a GSSContext to receive the incoming request * from the client. Use null for the server credentials * passed in. This tells the underlying mechanism * to use whatever credentials it has available that * can be used to accept this connection. */ GSSContext context = manager.createContext((GSSCredential)null); // Do the context eastablishment loop byte[] token = null; while (!context.isEstablished()) { token = new byte[inStream.readInt()]; System.out.println("Will read input token of size " + token.length + " for processing by acceptSecContext"); inStream.readFully(token); token = context.acceptSecContext(token, 0, token.length); // Send a token to the peer if one was generated by // acceptSecContext if (token != null) { System.out.println("Will send token of size " + token.length + " from acceptSecContext."); outStream.writeInt(token.length); outStream.write(token); outStream.flush(); } } System.out.println("Context Established! "); System.out.println("Client is " + context.getSrcName()); System.out.println("Server is " + context.getTargName()); /* * If mutual authentication did not take place, then * only the client was authenticated to the * server. Otherwise, both client and server were * authenticated to each other. */ if (context.getMutualAuthState()) System.out.println("Mutual authentication took place!"); /* * Create a MessageProp which unwrap will use to return * information such as the Quality-of-Protection that was * applied to the wrapped token, whether or not it was * encrypted, etc. Since the initial MessageProp values * are ignored, just set them to the defaults of 0 and false. */ MessageProp prop = new MessageProp(0, false); /* * Read the token. This uses the same token byte array * as that used during context establishment. */ token = new byte[inStream.readInt()]; System.out.println("Will read token of size " + token.length); inStream.readFully(token); byte[] bytes = context.unwrap(token, 0, token.length, prop); String str = new String(bytes); System.out.println("Received data \"" + str + "\" of length " + str.length()); System.out.println("Confidentiality applied: " + prop.getPrivacy()); /* * Now generate a MIC and send it to the client. This is * just for illustration purposes. The integrity of the * incoming wrapped message is guaranteed irrespective of * the confidentiality (encryption) that was used. */ /* * First reset the QOP of the MessageProp to 0 * to ensure the default Quality-of-Protection * is applied. */ prop.setQOP(0); token = context.getMIC(bytes, 0, bytes.length, prop); System.out.println("Will send MIC token of size " + token.length); outStream.writeInt(token.length); outStream.write(token); outStream.flush(); /* * Impersonate client */ System.out.println("Impersonating client."); /* * Extract the KerberosPrincipal from the client GSSName and populate * it in the principal set of a new Subject. Pass in a null for * credentials. If we were to pass in the delegated GSSCredential * instead of null, then the resulting Subject's private credential * set would also be populated. */ GSSName clientGSSName = context.getSrcName(); System.out.println("clientGSSName: " + clientGSSName); Subject client = com.sun.security.jgss.GSSUtil.createSubject(clientGSSName, null); /* * Construct an action that will read a file meant only for the * client */ PrivilegedAction readFile = new ReadFileAction(clientGSSName.toString()); /* * Invoke the action via a doAsPrivileged. This allows the * action to be executed as the client subject, and it also runs * that code as privileged. This means that any permission checking * that happens beyond this point applies only to the code being * run as the client. */ Subject.doAsPrivileged(client, readFile, null); /* * Clean up */ System.out.println("Closing connection with client " + socket.getInetAddress()); context.dispose(); socket.close(); } } }
ReadFileAction.java
import java.security.PrivilegedAction; import java.io.*; /** * This class implements the PrivilegedAction interface to demonstrate the * reading of a file that belongs to the client. This code will be * executed by the server while impersonating the client principal. */ public class ReadFileAction implements PrivilegedAction { private String fileName; /** * Contructs a ReadFileAction instance. * * @param kerberosPrincipalName the name of the Kerberos principal * who owns the file that will be read. The filename is constructed * from the name of the principal. */ public ReadFileAction(String kerberosPrincipalName) { /* * Separate the realm component from the name and use the rest of * it for constructing the filename. If the principal name is * "joe@REALM" then the file that will be read is * "data/joe_info.txt". The path separator "/" might be "\" in the * case of Windows. */ int realmSeparatorPos = kerberosPrincipalName.lastIndexOf('@'); fileName = "data" + File.separatorChar + kerberosPrincipalName.substring(0, realmSeparatorPos) + "_info.txt"; } /** * Does the actual reading of the file. It displays the text contained * in the file. */ public Object run() { System.out.println("==============================================="); System.out.println("Reading file: " + fileName); try { BufferedReader reader = new BufferedReader(new FileReader(fileName)); String str = reader.readLine(); while (str != null) { System.out.println(str); str = reader.readLine(); } } catch (IOException e) { System.err.println(e); } System.out.println("==============================================="); return null; } }
serverimp.policy
grant CodeBase "file:./Login.jar" { permission java.security.AllPermission; }; grant CodeBase "file:./SampleServerImp.jar" Principal javax.security.auth.kerberos.KerberosPrincipal "service_principal@your_realm" { permission java.net.SocketPermission "*", "accept"; permission javax.security.auth.kerberos.ServicePermission "service_principal@your_realm", "accept"; permission javax.security.auth.AuthPermission "doAsPrivileged"; }; grant CodeBase "file:./ReadFileAction.jar" Principal javax.security.auth.kerberos.KerberosPrincipal "your_user_name@your_realm" { permission java.io.FilePermission "data/your_user_name_info.txt", "read"; };
csImpLogin.conf
/** * Login Configuration for JAAS. */ SampleClient { com.sun.security.auth.module.Krb5LoginModule required; }; SampleServerImp { com.sun.security.auth.module.Krb5LoginModule required storeKey=true principal="service_principal@your_realm"; };