Java Enterprise in a Nutshell (In a Nutshell (OReilly))

10.1. Basic Security Concepts

Applications need multiple layers of security. Roughly speaking, these can be described as two high-level layers: transport layer security and application layer security . Transport layer security refers to protection of data while it's in transit across the network. Application layer security ensures that only authorized users gain access to the application and its data.

Before we discuss the issues related to transport and application layer security, let's have a quick primer on public-key cryptography, which plays an important role in common solutions to both areas of security concerns.

10.1.1. Public-Key Cryptography

Public-key cryptography is a powerful approach for secure operations that can be used for data encryption, digital signatures, and authentication and in various other security contexts. In the public-key cryptography model, each party participating in a secure exchange has two keys: a public key and a private key that fit together mathematically. The public key can be widely and openly published. Private keys, on the other hand, must be carefully guarded, since they can be used to create digital signatures. Public and private keys are used in conjunction with each other to perform highly secure operations. An encrypted data exchange, for example, is performed by encoding a message with the recipient's public key. It can then be decrypted only with the recipient's private key. In this way, only the intended recipient can decrypt the message.[*]

[*] Where digital signatures are not used, a shared key can be used to encrypt data instead.

Public-key methods are also a critical element of digital signatures. A digital signature is an encoded piece of information included with a message that ensures the recipient that the message came from the sender, not from some malicious third party impersonating the sender. The sender of a message takes the message contents and uses an algorithm called a one-way hash to generate a hash value for the message. This hash value is then encrypted with the sender's private key to generate the signature for the message. Like any public-key-encrypted message, the signature can be decrypted only with the sender's public key, which, as mentioned earlier, can be freely shared. Both the original message and the signature for the message are sent to the recipient together. Once received, the recipient can decrypt the signature using the sender's public key. Running the same one-way hash on the message should produce an identical hash value. If the hashes match, the integrity of the message is intact; the message was not modified in transit. If the message contents had been altered at some point between the sending and receiving of the message, the hash values would not match. In addition, since the hash was proven to be encrypted by the sender's private key, we know that the message came from the owner of the private key.

In the context of J2EE applications, the senders and recipients in this transaction are often components or systems rather than people, but the basic idea is the same.[*] However, it is important to point out that, while public-key cryptography is highly secure for end user authentication, creating a public-key infrastructure (PKI) that issues, expires, and revokes user certificates is daunting, and installing them on the client side, whether in hardware or software, also takes work. Only in some industries in which privacy is paramount can the business case for full-blown PKI be made. However, certificates are commonly used on a server-to-server basis to provide SSL encryption between applications, for example.

[*] It is easier to explain the concepts in this section using people as illustrations, but bear in mind that the user might be a component or class rather than a person.

10.1.2. Transport Layer Security: Integrity and Confidentiality

Security at the transport layer ensures the integrity as well as the confidentiality of the data as applications exchange the data over the wire.

Integrity protection ensures that data is not modified in transit, guaranteeing that the data sent is the data received. One technique for ensuring data integrity over the wire is the use of digital signatures in conjunction with message digests.

Confidentiality protection ensures that unauthorized parties cannot read data if they intercept it. The primary means to ensure this is to scramble, or encrypt, the data. One technique for ensuring the confidentiality of data in transit is Secure Sockets Layer (SSL).[*]

[*] SSL has become standardized as Transport Layer Security (TLS), defined in RFC 2246. SSL remains the more common term, and so we use it in this chapter.

10.1.3. Application Layer Security: Authentication and Authorization

Two fundamental concepts in application security are authentication and authorization . Authentication ensures that a user is who she says she is. Authorization assures that the user can access only the portions of the program and the data to which she is entitled.

Authentication refers to the process that a user or program uses to identify itself to the application. Authentication typically involves something you have, something you know, or something you are. Passwords, the most common authentication method, involve something you know. Digital signatures involve something you havea private key, whether stored on a hard drive or on a smartcardand something you know, the passphrase that guards the private key. Biometric authentication involves technology such as fingerprint readers, facial or voice recognition systems, and retinal scans. This approach is based on something you are (the whorls on your fingerprints or the modulation patterns in your voice). Biometric authentication is more rare, even in enterprise applications, but it exists and is becoming more broadly available. Some laptops even offer fingerprint-based authentication to access the computer system.

Authorization ensures that users have access only to the resources that they are allowed to access and may regulate what they can do (read but not modify data, initiate process X but not Y, etc.). The application server allows only authorized users access to given resources; otherwise, access to the resource is restricted. In a web application, these resources can be URLs or URL patterns. In the EJB tier, these resources can be components or a component's methods.

The problem with authorization is that specifying what resources each individual user can access is cumbersome. As the application changes, as people come and go, and as user roles change over time, all these settings must be kept up-to-date. In recognition of this security management issue, J2EE security is role-based. Rather than specifying authorizations on a per-user basis, you define them for a set of well-defined roles, such as customer, administrator, salesperson, student, and professor. Users are given permissions in the system by granting them one or more of these roles. Creating categories of users greatly streamlines authorization because you've defined the allowed combinations of permissions in one place (the role definitions), and a given user's authorizations are represented as a simple list of roles that he's been assigned.

Role-based authentication involves users, roles, permissions, and resources. A user provides a username and authentication credentials of some kind to the application. At that point, the authenticated user is considered by the application to have an identity, which is the username. Users have one or more roles. This classification of users makes it relatively easy to create fine-grained authorization policies. Instead of specifying authorizations for each individual user, you specify authorizations for a role. Therefore, a role is a grouping of permissions that a given type of user possesses. You typically specify authorizations as policies. You specify these policies, in a declarative programming model that we will discuss later, in special policy files, deployment descriptors, or special-purpose policy stores. An Access Control List (ACL) maps roles to resources. We will provide more details about how to do this for various kinds of applications later in this chapter.

Application server vendors may provide additional security services beyond the ones discussed earlier, such as auditing and nonrepudiation. Auditing services log security information for later review. These logs can be used to detect malicious attempts to break into applications, among other things. Nonrepudiation facilities provide proof of user actions in such a way that the user cannot later deny it (obviously a particularly good feature for business transactions).

Now that we've outlined these terms and concepts, the next section describes how the Java platform implements these basic security features. The J2EE security model leverages Java platform security.

Категории