Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 73 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
73
Dung lượng
1,07 MB
Nội dung
The toString method returns a string representation of this principal: String toString() The hashCode method returns a hash code for this principal: int hashCode() The getName method returns the name of this principal: String getName() When an entity submits itself to authentication, it must provide credentials (information that the security system can use to verify the entity). For example, a user logging in to a system must provide a username and password. Credentials Credentials can be of any type, and no requirements are placed on what interfaces a credential class must implement. However, JAAS provides two interfaces that bestow behavior on a credential class that might prove useful. These interfaces are Refreshable and Destroyable. The javax.security.auth.Refreshable is useful for a credential that requires a refresh of its state (perhaps the credential is valid only for a specific length of time). Four methods are defined on this interface. The isCurrent method should return true if the credential is current or return false if it has expired or needs a refresh of its state: boolean isCurrent() The refresh method refreshes the current state of the credential, making it valid again. The javax.security.auth.Destroyable interface gives a credential semantics for destroying its contents: void refresh() throws RefreshFailedException The isDestroyed method returns true if the credential’s contents have been destroyed and returns false otherwise: boolean isDestroyed() The destroy method destroys the contents of the credential: void destroy() throws DestroyFailedException Methods that require contents to be valid should throw the IllegalStateException after destroy is called. 669 Chapter 13: Java Security 18_777106 ch13.qxp 11/28/06 10:35 PM Page 669 Authenticating a Subject The basic manner in which a subject is authenticated is through a LoginContext object. A LoginContext then consults another class for the specific authentication services. The sequence of steps that occurs when a LoginContext is used for authentication is as follows: 1. A LoginContext object is instantiated. 2. The LoginContext consults a Configuration to load all LoginModules for the current application. 3. The login method of the LoginContext is called. 4. Each LoginModule then attempts to authenticate the subject. The LoginModule should associ- ate principals/credentials with a successfully authenticated user. 5. The success or failure of the authentication is communicated back to the application. Configuration The configuration file contains a number of configurations per application for authentication. Each configu- ration has a name (usually the application name) and then a list of login modules to use for authentication. The configuration can have one set of login modules under the name other to specify an authentication scheme to use when no others match the name specified. Each set of login modules adheres to the follow- ing syntax: NAME { LoginModuleClass FLAG ModuleOptions; LoginModuleClass FLAG ModuleOptions; } The LoginModuleClass is the fully qualified name of a LoginModule. The FLAG can be one of the val- ues in the following table. Flag Name Description Required The LoginModule is required to succeed; however, if it fails, Login Module s specified after the current one still execute. Requisite The LoginModule is required to succeed. If it fails, control returns to the application. No further LoginModules are executed. Sufficient The LoginModule is not required to succeed. If the LoginModule succeeds, control is immediately returned to the application. Control passes down the list of LoginModules even if this one fails. Optional The LoginModule is not required to succeed, and control passes down the list if this one succeeds or fails. The ModuleOptions is a space-separated list of login module-specific name=value pairs. 670 Part II: A Broad Understanding of Java APIs, Tools, and Techniques 18_777106 ch13.qxp 11/28/06 10:35 PM Page 670 LoginContext The LoginContext class provides a clean approach to authenticating subjects while leaving the authen- tication details to LoginModules. This makes it easy to change the configuration for an application by adding or removing a LoginModule. The LoginContext class provides the following constructors: public LoginContext(String name) throws LoginException public LoginContext(String name, Subject subject) throws LoginException public LoginContext(String name, CallbackHandler callbackHandler) throws LoginException public LoginContext(String name, Subject subject, CallbackHandler callbackHandler) throws LoginException The name parameter corresponds to an entry in the configuration used for the application. The first and third forms of the constructor create an empty subject because one isn’t passed in. If a LoginModule has to communicate with the user, it can do so through a CallbackHandler. For example, if a username and password are required, a class can inherit from javax.security.auth.callback.Callback Handler and retrieve the information from the user. The CallbackHandler interface defines a single method: void handle(Callback[] callbacks) throws java.io.IOException, UnsupportedCallbackException One or more callbacks can be specified, allowing you to separate username and password entries into two separate callbacks all managed by a single CallbackHandler. The LoginContext also provides login and logout methods. This method causes all configured LoginModules to authenticate the subject. If authentication succeeds, you can retrieve the subject via getSubject(). The subject may have revised credentials and principals after all authentication is performed: public void login() throws LoginException The logout method removes credentials/principals from the authenticated subject: public void logout() throws LoginException Essentially, the code used for an application to log in, obtain an authenticated subject, and then log out looks like the following snippet: LoginContext loginContext = new LoginContext(“BasicConsoleLogin”); try { loginContext.login(); // utilizes callbacks Subject subject = loginContext.getSubject(); // execute specific application code here loginContext.logout(); 671 Chapter 13: Java Security 18_777106 ch13.qxp 11/28/06 10:35 PM Page 671 } catch(LoginException le) { // authentication failed } The LoginContext retrieves the set of LoginModules to execute from the configuration under the name BasicConsoleLogin. Authorization Authentication provides for more of a black-and-white approach to security. The user (or other entity) is either authenticated or not. JAAS provides authorization for granting degrees of access to an entity. Each application can use a policy file that contains a list of permissions for various targets. The policy file pro- vides a way to grant permissions to both code and principals. The javax.security.auth.AuthPermission class exists to guard access to the Policy, Subject, LoginContext, and Configuration objects, providing a layer of security on these classes as well. Consult the documentation for this class for a full list of permissions that it provides. The policy file contains a list of grant sections that grant permissions to code or principals. The grant keyword is used to start a grant section, followed by zero or more optional elements: signedBy, codeBase, and principal. The basic format looks like the following: grant signedBy “signer_names”, codeBase “URL”, principal principal_class_name “principal_name”, principal principal_class_name “principal_name”, { permission permission_class_name “target_name”, “action”, signedBy “signer_names”; permission permission_class_name “target_name”, “action”, signedBy “signer_names”; }; You can only specify signedBy and codeBase a maximum of one time, but the principal element can be specified more than once. All of these are optional elements. By not specifying any at all, the permis- sions specified apply to all executing code, regardless of its source. As one example of a policy file, the java.policy that is located in the jre/lib/security directory that comes with Java has a policy that opens permissions wide to Java extensions: grant codeBase “file:${{java.ext.dirs}}/*” { permission java.security.AllPermission; }; The codeBase element is used to specify all code located in the java.ext.dirs (a system property) directory, which hence grants AllPermission to all code in the Java extensions directory. 672 Part II: A Broad Understanding of Java APIs, Tools, and Techniques 18_777106 ch13.qxp 11/28/06 10:35 PM Page 672 The signedBy element is used to grant permissions only when the code is signed by the specified entity. There are many available permissions in the Java API, such as java.io.FilePermission, java.net .NetPermission , and java.security.AllPermission. Each permission has its own set of actions, such as FilePermission, needing to know which operations are valid on a particular file (read, write, and so forth). Consult the online documentation for specific details on each permission. Summary In this chapter, you learned about Java cryptography and security. Security is very important in online systems and systems that have multiple users. You now know some of the basics of security, such as gen- erating and using keys, including digital signing and key management. Also introduced were the new XML digital signature packages. You have seen how Java supports a variety of security mechanisms from data encryption to access control, and you have an overview of how to go about securing your application. 673 Chapter 13: Java Security 18_777106 ch13.qxp 11/28/06 10:35 PM Page 673 18_777106 ch13.qxp 11/28/06 10:35 PM Page 674 Packaging and Deploying Your Java Applications This chapter describes how to package and deploy your Java applications including client-side and server-side applications. It discusses Java Web Start, JAR packaging, JAR signing, building WAR files, and CLASSPATH manipulation. You’ll walk through the different types of Java applica- tions and get a brief introduction to each as well as information on a few useful utilities that you can use when creating, configuring, and deploying your own applications. Examining Java Classpaths One of the most potentially frustrating aspects of Java is the classpath. If you have coded in Java even for a short length of time, you’re already familiar with the classpath. It is a system environ- ment variable that directs the Java Virtual Machine (VM) to a set of classes and/or JAR files. This is how the VM knows where code used by the program resides. At times, you wind up needing a class and have no idea which JAR file has this class. You might add a bunch of JAR files to your classpath, hoping you’ll accidentally add the right one in, never truly knowing which JAR files are not needed. Many people complain about DLL Hell on Windows, but a similar mismanagement of the classpath and the many files it points to can create the same sit- uation with Java. If you use a development environment such as Eclipse, you are somewhat insu- lated from this problem because it is easy to manage your classpath through the GUI. However, in a deployment scenario, you may not have the luxury of a graphical tool to help manage the classpath. A seemingly small problem (one JAR left off the classpath, for example) may take seconds to fix if you know where the class is or—if you don’t know—much longer. Also, having multiple versions of the same class in your classpath can lead to particularly difficult bugs to track down. Another problem with classpaths is length limits on the environment variable imposed by the operating system. I’ve seen more than one project with an insane number of JAR files (each with 19_777106 ch14.qxp 11/28/06 10:35 PM Page 675 a long path) specified within the classpath. Sometimes there is no great solution to this problem. If the classpath works and nobody needs to tweak it after deployment, you should be fine. However, long classpaths are troublesome during development and might even grow too long for the environment space after deployment. Here are a few suggestions to attempt to manage long classpaths. First, know where your application is executing from and utilize relative paths instead of absolute paths. Second, attempt to group your application and its libraries into as few JAR files as possible. A more complicated but useful solution is grouping the common utility JAR files (perhaps third-party JAR files used by your application) and plac- ing these in the extensions directory within the installed JRE. By default, this extensions directory is lib/ext beneath the JRE directory. By installing a JAR file as an extension, it no longer needs to appear on the classpath. You must ensure that the JAR file is placed within the correct JRE though. This might entail you installing your own JRE with your application, but this too cannot be done lightly. This should be only done with JAR files that are shared across multiple applications running within the same JRE. Using the relative path strategy is wiser for JAR files used by only a single application. In hoping to alleviate your burden a little, here are a couple of utility programs that may help you in managing your classpath. The first class is a straightforward utility that accepts a list of classes stored inside a file and verifies that each class is present somewhere within the classpath (or in one of the JAR files in the classpath). The file containing the class list is passed in on the command line. Each line in the file contains a single fully qualified class name: import java.io.*; public class ClassPathVerifier { public static void main(String args[]) { try { BufferedReader br = new BufferedReader( new InputStreamReader( new FileInputStream(args[0]))); String clsName=””; while( (clsName = br.readLine()) != null) { try { Class.forName(clsName); System.out.print(“.”); } catch(Exception e) { System.out.println(“\nNOT FOUND: “ + clsName); } } br.close(); } catch(IOException ioe) { System.out.println(“IOException: “ + ioe); ioe.printStackTrace(); } } } This class uses the simple technique of passing a class name into the Class.forName method. If no exception is thrown, the class is found. To show progress, a single period is printed for each class that is 676 Part II: A Broad Understanding of Java APIs, Tools, and Techniques 19_777106 ch14.qxp 11/28/06 10:35 PM Page 676 successfully loaded. If you manage multiple classpaths, this utility can be used to ensure that a set of classes is always available. A utility that packs more of a punch is listed next. The purpose of this next utility is to find which JAR file(s) a class is inside. You need not specify a fully qualified class name—any portion of the class name and package will do. This means that you can even search for a package instead of a particular class: import java.io.*; import java.util.zip.*; import java.util.StringTokenizer; public class ClassSearch { private String m_baseDirectory; private String m_classToFind; private int m_resultsCount=0; An interesting method that uses a bit more complex code is the searchJarFile. This method, shown in the following example, actually opens a JAR file and searches inside it for a given class name: public void searchJarFile(String filePath) { try { FileInputStream fis = new FileInputStream(filePath); BufferedInputStream bis = new BufferedInputStream(fis); ZipInputStream zis = new ZipInputStream(bis); ZipEntry ze = null; while((ze=zis.getNextEntry()) != null) { if(ze.isDirectory()) { continue; } if(ze.getName().indexOf(m_classToFind) != -1) { System.out.println(“ “ + ze.getName() + “\n (inside “ + filePath + “)”); m_resultsCount++; } } } catch(Exception e) { System.out.println(“Exception: “ + e); e.printStackTrace(); } } The findHelper method searches directories and subdirectories for JAR files: public void findHelper(File dir, int level) { int i; File[] subFiles; subFiles = dir.listFiles(); 677 Chapter 14: Packaging and Deploying Your Java Applications 19_777106 ch14.qxp 11/28/06 10:35 PM Page 677 if(subFiles == null) { return; } for(i=0; i<subFiles.length; i++) { if(subFiles[i].isFile()) { if(subFiles[i].getName().toLowerCase().indexOf(“.jar”) != -1) { // found a jar file, process it searchJarFile(subFiles[i].getAbsolutePath()); } } else if(subFiles[i].isDirectory()) { // directory, so recur findHelper(subFiles[i], level+1); } } } The method searchClassPath is used to find a class in the JAR files specified in the given classpath: public void searchClassPath(String classToFind) { String classPath = System.getProperty(“java.class.path”); System.out.println(“Searching classpath: “ + classPath); StringTokenizer st = new StringTokenizer(classPath, “;”); m_classToFind = classToFind; while(st.hasMoreTokens()) { String jarFileName = st.nextToken(); if(jarFileName != null && jarFileName.toLowerCase().indexOf(“.jar”) != -1) { searchJarFile(jarFileName); } } } The findClass method is kicked off from the main method and takes two parameters. One parameter is the base directory that will be used as a starting point to begin the class search. The second parameter is the class name that you are looking for. If the class name is found in any JAR files that exist in the base directory or its subdirectories, the JAR filename and location are printed out to the console: public void findClass(String baseDir, String classToFind) { System.out.println(“SEARCHING IN: “ + baseDir); m_baseDirectory = baseDir; m_classToFind = classToFind; m_classToFind = m_classToFind.replaceAll(“\\.”, “/”); File start = new File(m_baseDirectory); System.out.println(“SEARCHING FOR: “ + m_classToFind); System.out.println(“\nSEARCH RESULTS:”); findHelper(start, 1); 678 Part II: A Broad Understanding of Java APIs, Tools, and Techniques 19_777106 ch14.qxp 11/28/06 10:35 PM Page 678 [...]... JDK is installed in C:\Program Files \java\ jdk1 .6. 0: c:\ >java ClassSearch “c:\program files \java\ jdk1 .6. 0” RSAPrivateKey SEARCHING IN: c:\program files \java\ jdk1 .6. 0 SEARCHING FOR: RSAPrivateKey SEARCH RESULTS: com/sun/deploy/security/MozillaJSSRSAPrivateKey.class (inside c:\program files \java\ jdk1 .6. 0\jre\lib\deploy.jar) com/sun/deploy/security/MSCryptoRSAPrivateKey.class (inside c:\program files \java\ jdk1 .6. 0\jre\lib\deploy.jar)... files \java\ jdk1 .6. 0\jre\lib\deploy.jar) sun/security/mscapi/RSAPrivateKey.class (inside c:\program files \java\ jdk1 .6. 0\jre\lib\ext\sunmscapi.jar) sun/security/pkcs11/P11Key$P11RSAPrivateKey.class (inside c:\program files \java\ jdk1 .6. 0\jre\lib\ext\sunpkcs11.jar) java/ security/interfaces/RSAPrivateKey.class 67 9 Part II: A Broad Understanding of Java APIs, Tools, and Techniques (inside c:\program files \java\ jdk1 .6. 0\jre\lib\rt.jar)... META-INF/MANIFEST.MF 410 Wed July 21 21:28:58 EDT 2004 META-INF/MYSELF.SF 100 8 Wed July 21 21:28:58 EDT 2004 META-INF/MYSELF.DSA 68 8 Chapter 14: Packaging and Deploying Your Java Applications 0 0 0 0 0 0 sm sm sm s m k i = = = = Wed Wed Wed Wed Wed Wed July July July July July July 21 13: 36: 18 EDT 2004 META-INF/ 21 13:27:02 EDT 2004 chess/ 21 13: 26: 32 EDT 2004 chess/Chess .java 21 13: 26: 42 EDT 2004 chess/ChessGUI .java. .. 67 9 Part II: A Broad Understanding of Java APIs, Tools, and Techniques (inside c:\program files \java\ jdk1 .6. 0\jre\lib\rt.jar) java/ security/spec/RSAPrivateKeySpec.class (inside c:\program files \java\ jdk1 .6. 0\jre\lib\rt.jar) sun/security/rsa/RSAPrivateKeyImpl.class (inside c:\program files \java\ jdk1 .6. 0\jre\lib\rt.jar) This execution of the utility shows the various JAR files that contain either RSAPrivateKey... strong feature set and were able to be embedded in a Javasupporting web browser Applets still require a significant amount of download time and are still not as rich as a thick client is Java Web Start is based on the Java Network Launch Protocol (JNLP) and the Java 2 platform Java Web Start was introduced as a standard component in Java 1.4 Because of Java Web Start’s unique architecture, it only takes... 21, 2004, keyEntry, Certificate fingerprint (MD5): 96: 0B:2C:20:EA:DB:87:7A :64 :DA:9F :68 :21:85:B6:9A The output shows the type of keystore you are using, the provider, and the certificate fingerprint If you get the preceding printout, you are ready to sign the JAR file In order to sign the JAR file, you must now 68 7 Part II: A Broad Understanding of Java APIs, Tools, and Techniques use the jarsigner tool... package Again, the Java plug-in will compare the vendor IDs to make sure it is getting the correct optional package (extension)Implementation-URL In order for the Java plug-in to know where to get the latest version of the package, this attribute would have to be set with the URL that tells the Java plug-in where to download the latest optional package 68 5 Part II: A Broad Understanding of Java APIs, Tools,... program via its ARG list in the main method of the application Analyzing Applets Java applets are one of the notable features of the Java programming language Applets are programs that are designed to run within web browsers that are compatible with and support Java Applets can be 69 1 Part II: A Broad Understanding of Java APIs, Tools, and Techniques embedded directly in HTML and can be used on web... board.bmp Chess .java ChessGUI .java meta-inf Manifest.mf Figure 14-2 You can also use the jar tool to see the contents of the chess.jar file by specifying the t option on the file Here is an example of how to view the table of contents of a JAR file: C:\>jar -tf chess.jar META-INF/ META-INF/MANIFEST.MF chess/ chess/Chess .java chess/ChessGUI .java chess/images/ chess/images/board.bmp 68 3 Part II: A Broad... entire chess directory (see Figure 14-1) 68 2 Chapter 14: Packaging and Deploying Your Java Applications as well as any subdirectories under it The c option is used to create the archive, the v option specifies verbose, and the f option signifies that you will be supplying the name of the JAR file to create on the command line images chess board.bmp Chess .java ChessGUI .java Figure 14-1 W# W# Here is an example . Security 18_7771 06 ch13.qxp 11/28/ 06 10: 35 PM Page 67 3 18_7771 06 ch13.qxp 11/28/ 06 10: 35 PM Page 67 4 Packaging and Deploying Your Java Applications This chapter describes how to package and deploy your Java. assumes that the JDK is installed in C:Program Files java jdk1 .6. 0: c:> ;java ClassSearch “c:program files java jdk1 .6. 0” RSAPrivateKey SEARCHING IN: c:program files java jdk1 .6. 0 SEARCHING. files java jdk1 .6. 0jrelibextsunpkcs11.jar) java/ security/interfaces/RSAPrivateKey.class 67 9 Chapter 14: Packaging and Deploying Your Java Applications 19_7771 06 ch14.qxp 11/28/ 06 10: 35 PM Page 67 9 (inside c:program files java jdk1 .6. 0jrelib
t.jar) java/ security/spec/RSAPrivateKeySpec.class (inside