Security and Single Sign-On - Pdf 63

209
CHAPTER 8
Security and Single
Sign-On
S
ECURITY AND
S
INGLE
Sign-On (SSO) are not unique to portlets, but when consid-
ering their implementation you must take into account some special advantages,
disadvantages, and responsibilities.
A portlet has some security advantages over a conventional application. You
do not have to concern yourself with obtaining a login from the user, for example—
this is the responsibility of the container.
You do still have some responsibilities; your portlet must manage access to
its resources. For example, a corporate address book should probably be accessible
only to employees of the company, whereas a private address book should in gen-
eral be accessible by only one person.
A portlet may obtain information from external resources, so you also need
to be aware of the options for passing security information around—possibly
over the network.
While the developer’s natural inclination is to “Keep It Simple, Stupid” (KISS),
it is no longer a safe assumption (if it ever was) that the network is secure by
default. Avoiding security vulnerabilities adds a regrettable but necessary level
of complexity to the design of any portlet acting as the gateway to sensitive
information.
This chapter discusses the standards, protocols, and APIs that are required to
implement secure portlets. The security mechanisms specified in the portlet API
are the most basic level of portlet security. We discuss SSO strategies for portals,
including authentication with Java Authentication and Authorization Services
(JAAS). We also demonstrate how to use the Java Generic Security Services

Portlet
Web Mail
Application
Authentication
Server
Legacy E-mail
Database
Portal
(Portlet Container)
Figure 8-1. Portlet security interactions
2840ch08.qxd 7/13/04 12:44 PM Page 210
Download at Boykma.Com
Security and Single Sign-On
211
Similarities to Servlet Security
Since a portlet is generally contained within a servlet, it should come as no great
surprise to discover that a portlet behaves quite like a servlet in its provision of
security mechanisms.
The
HttpServletRequest
object provided with requests to a servlet is required
to offer the following four methods:
public String getAuthType()
public String getRemoteUser()
public boolean isUserInRole(String role)
public Principal getUserPrincipal()
The information provided by these four methods is in turn made available
directly to a portlet via the
PortletRequest
object. The same four methods are avail-

Digest authentication is about halfway between Basic and Client Certificate
authentication. The username and password are not sent in plaintext; instead they
are sent as a message digest, which prevents the password from being retrieved.
However, as with basic authentication, the identity of the server is not verified
and the exchange is carried out over an unsecured connection so there is still some
degree of vulnerability.
NOTE
A message digest is an arbitrarily short representation of a message.
A “hash function” is applied to the original message to produce this short rep-
resentation. A trivial example of a hash would be one that counted the
number of words in the message.
A more typical example is the MD5 algorithm, which will reduce a message of
any length to 16 representative bytes. The chances of any two messages pro-
ducing the same digest are astronomically small, and it is effectively
impossible to reverse-engineer the original message from its MD5 hash.
This makes the MD5 hash perfect for confirming a password over a network.
The remote server will send the client a random “salt” text. This is added by
the client to the password, and the digest is computed. The client sends the
digest to the server, which will compute the digest independently and com-
pare it with the client’s digest. If they match, both machines must know the
password, but an eavesdropper cannot reproduce the digest independently
(without knowing the password).
The use of a salt prevents a third party from simply retransmitting the digest,
since it will be different for every salt value.
Form-based authentication is one of the most commonly used forms of authen-
tication, largely because it can be made secure and offers cosmetic advantages
over web client–managed mechanisms. The username and password are sub-
mitted as plaintext in a form request. If the POST mechanism is used and the
connection is over HTTPS (SSL) rather than HTTP, this cannot easily be inter-
cepted. The

to avoid ambiguities.
Obtaining a Principal
The principal represents a user (or service, or server) whose identity has been
confirmed by the portal. It is distinct from a username, because there is no prin-
cipal for an unauthenticated user. Note that in practice
getRemoteUser()
is likely
to return null for unauthenticated users anyway, because the authentication process
is often the mechanism by which the user is established.
The
getUserPrincipal()
method therefore returns the
Principal
object asso-
ciated with the current logged-in user, or null if the user has not been logged in.
You may not immediately see the need for a separate object to represent this—
surely one could use a combination of the username and an
isAuthenticated()
method? However, the principal serves an important purpose when you wish to
indicate to another service that our service is entitled to act on behalf of the user
in question.
NOTE
This sort of situation arises often with portals, because they can aggre-
gate quite distinct systems into a common interface. Take as an example an
investment bank’s systems. There may be distinct systems for bond and equi-
ties trading, and these systems in turn talk to a set of back-end databases.
When using a portal to unify the systems, users must first present their cre-
dentials to the portal, which in turn establishes a Principal, which is passed
to the bond system and the equities system. These in turn use it to gain access
to the back-end databases. By using the end user’s credentials all the way

false
appropri-
ately. If the current user is null (i.e., not logged in), this method will always return
false
.
Since the mappings of the native security system may not correspond naturally
to those of the portlet application (or indeed to those of a servlet application),
a facility is provided to allow a security role to be mapped to an additional name,
in effect allowing the developer or deployer to assign aliases to roles.
As is normal with servlets, an entry can be placed in the portlet application’s
web.xml deployment descriptor file to specify a
<security-role-ref>
element for
an existing role name. The format is
<security-role-ref>
<role-name>ForumModerator</role-name>
<role-link>Administrator</role-link>
</security-role-ref>
In this example, the native role of Administrator is mapped to the applica-
tion role of ForumModerator.
Working with portlets you may also specify a mapping in the same form within
the
<portlet>
element of the portlet.xml file.
When
isUserInRole()
is called, the system checks each file in turn, so if no
suitable role name is listed in the portlet.xml, the system checks the web.xml. If
that in turn contains no suitable role name entries, the native security system will
be tested for the appropriate principal’s role memberships.

Our examples use the Kerberos v5 software from MIT, as this is the
reference implementation of the standard. The example code would require
changes to work with Microsoft Active Directory.
Using Proxy SSO
Proxy SSO, as the name suggests, uses a proxy system to carry out sign-ons for us.
Users log into the portal with their username and password, and this in turn
unlocks a store of usernames and passwords for external systems.
The advantage of this system is that, as presented, it offers the same user
experience as True SSO. However, it is something of a compromise and this can
cause administrative problems.
2840ch08.qxd 7/13/04 12:44 PM Page 215
Download at Boykma.Com
Chapter 8
216
The approach necessitates management of the passwords for the systems.
Different legacy systems may require password changes at different times. Users
will still have to remember (or, dangerously, write down) the individual passwords
so that they can change them when they expire, or alternatively the passwords will
need to be set not to expire at all, which is in itself a security risk. For seamless
integration, the proxy SSO server would need to manage the life cycle for each
username and password pair. If the proxy SSO server had rules for each legacy
system that dictated the password expiration, the range of valid password values,
and the ability to change passwords, this could all be managed for the user. The
integration development costs for a project like this would be very high.
Because the passwords must be retrieved in order to present them to the
legacy systems, they must be stored by the proxy SSO solution in an encrypted
form that decrypts to plaintext. This is generally considered undesirable. More
desirable would be a solution that stores a message digest or hash of the password,
so the original password cannot be reconstructed.
Using a Common Registry

The portlet generally obtains a principal in this manner, so you can get by
without knowing how to do this manually. However, it is enlightening to see the
mechanism used in practice, and in some SSO scenarios—especially the proxy
scenario—it can be necessary.
At the point that you conduct a login, some details of the login mechanism must
be known. You cannot generally log in to a Unix system using NTLM (Microsoft)
authentication, and most authentication systems provide no discovery mechanism
to determine the protocol in use.
JAAS is therefore based on an API called Pluggable Authentication Modules
(PAM), which allows you to try a login on a system or systems using a variety of
different protocols. As a result, you can conduct a JAAS login, at the end of which
one or more systems may have vouched for your credentials.
The protocols to be used are generally specified using a configuration file.
This can contain individual or multiple entries.
// Kerberos.config
ClientAuthentication
{
com.sun.security.auth.module.Krb5LoginModule required;
};
ServerAuthentication
{
com.sun.security.auth.module.Krb5LoginModule required storeKey=true;
};
Here we have specified two distinct configurations. One is for our client, and
the other for a server that we will be demonstrating later in the chapter. For the
client authentication, a
LoginModule
has been specified, and we have indicated
that a login using this module is required in order to consider the authentication
successful. Additional parameters may be provided (as shown in the server exam-

The example application to conduct a JAAS login in Kerberos follows:
import javax.security.auth.*;
import javax.security.auth.callback.*;
import javax.security.auth.login.*;
public class Authentication {
public static class KerberosCallbackHandler implements CallbackHandler {
public KerberosCallbackHandler(String principal, String password) {
this.principal = principal;
this.password = password;
}
public void handle(Callback[] callbacks) {
for (int i = 0; i < callbacks.length; i++) {
Callback callback = callbacks[i];
if (callback instanceof NameCallback) {
((NameCallback) callback).setName(principal);
} else if (callback instanceof PasswordCallback) {
((PasswordCallback) callback).setPassword(
password.toCharArray());
}
}
}
private String principal;
private String password;
}
public static void setKerberosSystemProperties() {
System.setProperty(
"java.security.auth.login.config",
"./Kerberos.config");
2840ch08.qxd 7/13/04 12:44 PM Page 218
Download at Boykma.Com

setKerberosSystemProperties();
System.out.println("Attempting jaasLogin");
try {
Subject subject =
jaasLogin("ClientAuthentication", principalName, password);
System.out.println("Logged in " + subject);
} catch (Exception e) {
System.out.println("JaasLogin Failed: " + e);
e.printStackTrace();
}
2840ch08.qxd 7/13/04 12:44 PM Page 219
Download at Boykma.Com
Chapter 8
220
System.out.println("OK, Done.");
}
}
In the main method, we provide a principal name (username) and password.
We then invoke
setKerberosSystemProperties()
to specify Kerberos configuration
values. These could equally well be provided on the command line or extracted
from a properties file, but for the sake of clarity we’re setting them explicitly in
the code. First, we specify the location of the configuration file to use:
System.setProperty(
"java.security.auth.login.config",
"./Kerberos.config");
Then we assign the name of the Kerberos realm that the user should be
logged in to:
System.setProperty("java.security.krb5.realm", "JETSPEED");


Nhờ tải bản gốc

Tài liệu, ebook tham khảo khác

Music ♫

Copyright: Tài liệu đại học © DMCA.com Protection Status