Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 425 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
425
Dung lượng
1,72 MB
Nội dung
Part IX: Enterprise Access Chapter List Chapter 26: Java Enterprise Security and Web Services Security Chapter 27: Securing Client-Side Components Chapter 28: Securing Server-Side Components Chapter 29: Application Security with Java Summary To understand the PKI, only two things need to be studied in detail, the X.509 format and how digital certificates are managed in a certificate chain From those two things you get a lot of information about other protocols such as X.500, LDAP, and asymmetric keying The purpose of PKI is to transport a secure public key from a sender of a secure message to the receiver of a secure message so that he may decrypt the message PKI is a means to make the public key secure Java has a lot of packages for both formatting the X.509 digital certificate and checking the certificate path The LDAP SDK also offers a rich API for working with an LDAP server The LDAP server is important because the X.509 certificate format and certificate path are tightly coupled with the X.500 Directory Service schema for manipulating certificates The study of PKI is very extensive and a lot of work could go be required from an organization to support PKI My suggestion is to take the easiest route Use LDAP if you can, so that a lot of RDBMS work is not required Know the services offered by your CA, Web services, and Application services so that you may take advantage of them I have worked with many companies and types of developers, and many do think that it is cool to write their own LDAP server; however, there is a difference between having to write an LDAP server the night before production and writing one on your own time Use as much out-of-the-box functionality as possible Many organizations use PKI, so there are very few things to be discovered in this area for most organizations unless you happen to be an RA or a CA Chapter 26: Java Enterprise Security and Web Services Security In This Chapter By now you should be familiar with the basic tools for security, such as encryption, digital keys, and digital signatures, and you should know about the different security technologies provided by J2EE and the J2SDK v 1.4 This chapter helps you understand how those technologies come together in the overall Java security architecture and their application in Web Services These technologies form a security framework that allows you to switch among services You do not need to implement everything at once, and the framework provides you with a roadmap for your security architecture The next few chapters explore in more detail how this architecture is used in the client side (Chapter 27), the server side (Chapter 28), and how some applications provide security using these technologies (Chapter 29) Chapter 27: Securing Client-Side Components }; The RichJAAS entry is defined in the JAAS application's LoginContext when created The RichCallbackHandler is an implementation of the CallbackHandler interface for the login module to get the input information for username, passwords, any text, and confirmations The LoginContext could also pass in the username and password through the CallbackHandler to be grabbed by the login module at a later time Listing 19-10 shows the RichCallbackHandler class Listing 19-10: The RichCallbackHandler class: An example of runtime definitions package com.richware.chap19; import java.io.*; import java.security.*; import javax.security.auth.*; import javax.security.auth.callback.*; /** * Class RichCallbackHandler * Description: This is a Sample Callback Handler * * Copyright: Copyright (c) 2002 Wiley Publishing, Inc * @author Rich Helton * @version 1.0 * DISCLAIMER: Please refer to the disclaimer at the beginning */ public class RichCallbackHandler implements CallbackHandler { /** * Constructor RichCallbackHandler */ public RichCallbackHandler() {} /** * Method handle * Description: Retrieve or display the information requeste * provided Callbacks * * * @param callbacks - an array of Callback objects provided * security service which contains the information requested * or displayed * @throws IOException - if an input or output error occurs * @throws UnsupportedCallbackException - if the implementat * method does not support one or more of the Callbacks spec * callbacks parameter * */ public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { for (int i = 0; i < callbacks.length; i++) { if (callbacks[i] instanceof TextOutputCallback) { /* * Display the message according to the specified type */ TextOutputCallback toc = (TextOutputCallback) callbacks[i]; switch (toc.getMessageType()) { case TextOutputCallback.INFORMATION : System.out.println(toc.getMessage()); break; case TextOutputCallback.ERROR : System.out.println("ERROR: " + toc.getMessage()); break; case TextOutputCallback.WARNING : System.out.println("WARNING: " + toc.getMessage()); break; default : throw new IOException("Unsupported message type: " + toc.getMessageType()); } } else if (callbacks[i] instanceof NameCallback) { // Prompt the user for the username NameCallback nc = (NameCallback) callbacks[i]; System.err.print(nc.getPrompt()); System.err.flush(); nc.setName( (new BufferedReader( new InputStreamReader(System.in))).readLine()); } else if (callbacks[i] instanceof PasswordCallback) { /* * Prompt the user for the username */ PasswordCallback pc = (PasswordCallback) callbacks[i]; System.err.print(pc.getPrompt()); System.err.flush(); /* * Note: JAAS specifies that the password is a char[] than a String */ String tmpPassword = (new BufferedReader(new InputStreamReader(System in))).readLine(); int passLen = tmpPassword.length(); char[] password = new char[passLen]; for (int passIdx = 0; passIdx < passLen; passIdx++) { password[passIdx] = tmpPassword.charAt(passIdx); } pc.setPassword(password); } /* * Confirmation callbeack for KeyStore */ else if (callbacks[i] instanceof ConfirmationCallback) { // Prompt the user for the username ConfirmationCallback nc = (ConfirmationCallback) callbacks[i]; } else { throw new UnsupportedCallbackException( callbacks[i], "Unrecognized Callback"); } } } } Using the KeyStore login module, as defined in Listing 19-9, the login module requests information that it needs to log in a user using the RichCallbackHandler The RichCallbackHandler prompts the user for the information that it requires Listing 19-11 demonstrates the interaction for the alias richh and rich3 with the callback handler interaction Listing 19-11: Callback handler interaction >ECHO ENSURE that richjaas.jar and jaasaction.jar are in the C ENSURE that richjaas.jar and jaasaction.jar are in the CLASSPA >ECHO ENSURE that the keystore file is in the root drive of C: ENSURE that the keystore file is in the root drive of C:\ >java -Djava.security.manager Djava.security.auth.login.config=jaas.config Djava.security.policy=jaasapp.policy com.richware.chap19.JAASA Please login to keystore Keystore alias: richh Keystore password: password Private key password (optional): password Login succeeded JAAS has many secrets There is much to know In Listing 19-11, the alias richh from the keystore is allowed to log in and access the file secretinfo.txt The alias rich3 from the keystore receives a java.security.AccessControlException when trying to access the secretinfo.txt file, but is allowed to log in because the alias is listed in the keystore If the alias were not in the keystore, a javax.security.auth.login.FailedLoginException would occur CrossReference See Chapter 8 for more on the keystore and policytool The user richh is allowed to access the resources because the permissions for the common name in the keystore are given access in Listing 19-12 Listing 19-12: The permissions /* AUTOMATICALLY GENERATED ON Sun Feb 03 23:56:54 MST 2002*/ /* DO NOT EDIT */ grant codeBase "file:./richjaas.jar" { permission java.security.AllPermission; }; grant codeBase "file:./jaasaction.jar", principal javax.security.auth.x500.X500Principal "CN=Ric Helton,OU=development,O=richware,L=denver,ST=co,C=us" { permission java.security.AllPermission; }; The policy file in Listing 19-12 is generated with the policytool utility The security policy is defined at runtime in the system property -Djava.security.policy=jaasapp.policy The principal is defined to have access to all system resources The alias richh maps to the principal javax.security.auth.x500.X500Principal entry and allows the permission to all resources Any other principal does not allow any permission to access any resources in the jaasaction.jar where the JAAS privileged action is defined The privileged action contains the authorization components of JAAS that are executed by a subject A subject is the implementation of the javax.security.auth.Subject class The subject class is created with the associated principals, such as the username or the X500Principal in this example, and any credentials whether they are public or private Public credentials are public keys such as the password for the user, and private credentials are the private keys such as the private key in the X.509 certificate in the keystore The subject is created in the login module after a successful login has completed, and it is used by the login context to execute any privileged action using the subject's information In the examples given so far, the login context uses the getSubject method to retrieve the subject from the login module and executes privileged code with the doAs method The LoginContext completes a two-phase authentication process in order to create a subject A two-phase authentication process means that after the login() method is initialized, either a commit() or abort() method is invoked A commit() method finishes any processing after a valid login, and the abort() method performs cleanup after a login is invalid and the module needs to be returned to an initialized state Since the LoginModules are stackable, the LoginContext looks for a valid commit from all the modules to ensure that valid authentication takes place Also, the higher module doesn't commit until the bottom module commits, so that if an abort happens for the last authentication, the LoginContext aborts the previous modules After a valid authentication succeeds, the module populates the subject, and the LoginContext can now access the subject with the getSubject() method This gives the LoginContext a valid subject to use for authorization If a valid authentication has not succeeded, there is no subject for the LoginContext to use for the next phase of security in authorization Figure 19-2 shows this class interaction Figure 19-2: Java Authentication Class interaction Note The subject assigned to LoginModule is a placeholder to pass principal and credential information It does not associate the principal names and credentials until the authentication is completed In the example, the principal is the X500Principal string and the credentials are the X509 certificate that is retrieved from the keystore The alias and passwords for the keystore are authentication information and not the subject More detail for the CallbackHandler and Callbacks The JAAS Callback is how information, such as username and password, is passed between the application and LoginModule The list of Callbacks contains the information, and the CallbackHandler is the mechanism for passing the Callback information When the LoginModule gets the login method, it requests the login and may request information such as the username and the password, from the CallbackHandler's handle method that is defined in the login context The requesting information is dependent on the login module that is defined For instance, in the KeyStoreLoginModule there was a request for an alias name, a password for the keystore, a password for the alias, and a confirmation Many other login modules may only require the username and password The alias name and username were prompted for and sent back in the NameCallback The passwords were prompted for and returned in the PasswordCallback Listing 19-13 shows another example to populate the callback list These callbacks are passed through an array of Callbacks; the array contains the various pieces of information to pass to the application depending on what is required from the LoginModule Listing 19-13: Populating the callback list /* * Populate callback list */ Callback[] callbacks = new Callback[2]; callbacks[0] = new NameCallback("username: "); callbacks[1] = new PasswordCallback("password: ", false); try { /* * Prompt for username and password */ callbackHandler.handle(callbacks); /* * Retrieve username */ username = ((NameCallback) callbacks[0]).getName(); /* * Retrieve password, converting from char[] to String */ char[] charPassword = ((PasswordCallback) callbacks[1]).getPassword(); if (charPassword == null) { /* * Treat a NULL password as an empty password, not NULL */ charPassword = new char[0]; } password = new String(charPassword); } Following are several callback types that you can use: javax.security.auth.callback.ChoiceCallback is used to give a user, through the application, a set of choices to select from for the LoginModule javax.security.auth.callback.ConfirmationCallback is the callback that allows the LoginModule to prompt the application for extra authentication This information is in the form of a question where a yes/no, yes/no/cancel, or similar answer is processed There are possible options that are passed to the application with the selection index used to understand which one was selected from the user A message should normally be prompted to the user, through the application, in the form of a String javax.security.auth.callback.LocaleCallback is the callback needed if the LoginModule needs locale information from the application to determine country and language information for the user The information is passed to the LoginModule in the form of the Java's Locale javax.security.auth.callback.NameCallback is the callback object used to pass a name to the CallbackHandler The the name is in the form of a String javax.security.auth.callback.PasswordCallback is the password object to support the CallbackHandler The password is stored in the form of an array of characters javax.security.auth.callback.TextInputCallback allows the login modules to retrieve arbitrary text from the application This data is in the form of a String javax.security.auth.callback.TextOutputCallback allows the LoginModule to send informational or warning information to the application This takes the form of a String message and a message type The type of message matches one of these static values of INFORMATION, WARNING, or ERROR More on the configuration file setup The JAAS login configuration file defines the login modules to be used, and the entries to be used are defined in the creation of the LoginContext objects The configuration file is defined by the property settings of the system environment in the java.security.auth.login.config definition The associated login module class defines each login module in the configuration Listing 19-14 defines an example configuration where two LoginModules are required to be used for the underlying login This contains a list of login modules used for that application The authentication proceeds down the list in the exact same order as the modules that have the REQUIRED field set Listing 19-14: A configuration file example Login{ com.sun.security.auth.SampleLoginModule REQUIRED debug=true; com.sun.security.auth.NTLoginModule REQUIRED debug=true; } There are four flags to define when the associated login module is to be used: They are the REQUIRED, REQUISITE, SUFFICIENT, and OPTIONAL flags REQUIRED The login module is required to succeed The authentication proceeds to the next login module down the chain regardless of whether it succeeded or failed All required login modules must succeed in order for the authentication to succeed REQUISITE The login module is required to succeed The authentication returns immediately to the application if the authentication fails; otherwise, it returns to the next login module down the chain All requisite login modules must succeed in order for the authentication to succeed SUFFICIENT The login module is not required to succeed If it succeeds, it returns immediately to the application without proceeding down the chain; otherwise, it proceeds down the chain OPTIONAL The login module is not required to succeed The authentication proceeds to the next login module down the chain regardless of whether it succeeded or failed At least one of the OPTIONAL or SUFFICIENT modules must succeed in order for an authentication to succeed Chapter 1: Security Basics In This Chapter This chapter is intended to provide a basic introduction to security concepts that I call the pillars of security: authentication, authorization, confidentiality, and integrity These concepts are used throughout the book I do not intend to present a complete discussion on all the details of security in this chapter; instead, my intention is to establish the basic terminology to be built on and to be addressed in detail later Security is a complicated topic and having a common understanding of the terminology and concepts is a good starting point If you are already familiar with authentication, authorization, confidentiality, and integrity, you can skip this chapter entirely ... Chapter 26: Java Enterprise Security and Web Services Security Chapter 27: Securing Client-Side Components Chapter 28: Securing Server-Side Components Chapter 29: Application Security with Java Summary... IIOP and presents how the EJB container can be configured and how it provides security Chapter 29: Application Security with Java In This Chapter As discussed throughout this book, security is more than network security - it affects the entire enterprise solution... organizations unless you happen to be an RA or a CA Chapter 26: Java Enterprise Security and Web Services Security In This Chapter By now you should be familiar with the basic tools for security, such as encryption, digital keys, and digital signatures, and you should