Security and WebObjects
by David Neumann

This is a practical guide to applying various common forms of security to your WebObjects applications. These include basic how-tos as well as higher-level security discussions (when to use encryption, integrating different public key infrastructures, and B2B applications). 

By some definitions there are three aspects of Security:
    - Secrecy, 
    - Integrity, and 
    - Availability

This paper will focus on Secrecy with some attention to Integrity. There are many different aspects of Secrecy:  authentication, encryption, access control, intrusion protection.

Encryption and Cryptography

The most common form of encryption used everyday by end users is the public key cryptography implemented as part of the Netscape SSL protocol.  However even this mechanism also uses private key cryptography (for bulk encryption).  So what's the difference between these?  The following section gives a quick primer on private and public key cryptogrpahy (or crypto) and how these techniques are used in web transactions that use SSL. Following this are discussions the practical application of SSL and encryption in WOApps.

Crypto Primer

There are a number of important terms that should be well understood when using cryptography and securing data systems. Some of these are: digital signature, RSA, public key crypto, secret key crypto, DES, hash algorithms, plaintext, cyphertext, CA, VA, PKI, and nonrepudiation.

Secret key crypto is about sharing a secret. If you know the secret password (or key) you can feed that into an algorithm like DES (the Digital Encryption Standard) to encrypt plaintext or decrypt cyphertext.  This is what most people think of when they think of security. If you know the password, then a relying party assumes you are who you claim to be; having the shared secret also means you can decrypt what the other party encrypted for you.  However with public key crypto you can prove that you know the secret without giving that secret to anyone. And that's a pretty neat trick.

    Why is this distinction important?  Well, having an encrypted connection between you and a party is great when you want to, say, buy something but you don't want anybody to see private information. On the web, this private information is mainly the credit card number. Unfortunately if you are using secret key cryptography, either:  
    1) everyone on the Net needs to know the secret to access your site securely (which means it isn't a secret), or
    2) you have to create and share a unique secret with each of your customers. 
The problem with the latter case is two-fold: how can I exchange a secret with my partner in the first place if I have no secure channel to begin with? You can't. Instead you need to have established a separate secure channel ahead of time to exhange a secret. Furthermore it's a logistical pain: for every partner I want to do business with, I need to establish this secure channel. This secure channel can be personal contact, a telephone call, or snail mail, etc.  

Although the NSA probably already had a version of it, it wasn't until the RSA algorithm came along that public key crypto arrived in force to help solve this key exchange problem. 

Public key crypto means there are now two keys associated with encrypting data: a public key you spread everywhere, and a private key you keep secret and that you never share.  One key is used to encrypt while the other is used to decrypt. If you encrypt something with your private key, only your public key can decrypt it.  If you encrypt something using someone else's public key, only their private key can decrypt it.
   So let's go back to the key exchange problem. Now when I access a web site (Acme Corp) and I want to make sure the info I send there is encrypted, I need to get the public key of the web site operator. This is information that is in the public domain. Therefore the key exchange process that used to be so difficult and slow can now be done completely in the clear. In fact it can be done online at the time of my transaction. Once I have this public key for Acme, I then encrypt my data with it and send the data to the Acme web site. Only the web site with the Acme private key can decrypt my data.  If someone tries to spoof (fake that they are Acme Corp), they can certainly do so, but it won't do them any good because they would not be able to decrypt the data I sent them.

Except that there is still a hole here... how do I know the public key I have associated with Acme is indeed the real Acme corporation?  Well, I don't.  Acme could run a very expensive ad campaign to spread this key so it would be impractical for an impostor to pretend to be Acme. This isn't too desirable though. What's needed is a third party that everyone already trusts and that certifies the association between an entity and that entity's public keys.  This kind of trusted third party is called a Certificate Authority (or CA) and the document a CA issues binding identity and public key is called a Digital Certificate. In many ways the relationship between a CA and Acme is similar to that which was required when exchanging keys in a private key crypto environment. Acme has to supply enough evidence to prove that they are who they claim to be. This could involve interviews, D&B research, etc. Unlike the secret key problem, this tedious relationship only has to happen once... between the Acme and the CA.  Everyone trusts that the CA is doing such background checks before issuing a certificate and that's why Joe User trusts the CA without having to do this research and checking themselves.
   The digital certificates issued by a CA have two parts.  The content of the certificate (name, address, public key, etc.), and the CA's digital signature. A digital signature is what you get when you hash a document and then encrypt the hash with a private key. 
   
The goal of the SSL protocol was to implement this public key crypto key exchange between parties on the web. When you access Acme's SSL web site, you receive the server's digital certificate (or cert). Your client validates that the cert is signed by a trusted CA and satisfies some test that only the holder of the private key can pass. If this phase goes well, the client encrypts its content to the server using the server's public key.  An optional phase can also be performed at the request of the server for the client to authenticate to the server in the same fashion as the server authenticated to the client. In other words, the client can have a certificate as well.  Perhaps the most broadly distributed consumer digital certificate in the world is the kind embedded in the American Express Blue Card. Still most online merchants do not require certificate authentication and rely instead on username/password. However more and more B2B relationships are leveraging digital certificates on both the server and client ends. Nonrepudiation is a big reason.  

The only big security hole left in this scheme is whether the otherwise good certificate has been revoked. To plug this hole a party can use a Validation Authority or VA. Or at least elect to download and search a signed document called a certificate revocation list (or CRL).  A VA is not really a new concept. You use one every time you use your credit card. Regardless of whether your card was issues by MasterCard, VISA, or AMEX, etc., when you buy something with it, your card is validated by a company called VeriFone. VeriFone consults a database of credit card revocation lists to see if your card is still good before authorizing your transaction.  A company called ValiCert does exactly the same thing but for digital IDs instead of credit cards.

SSL

Encryption for most developers and users means securing a connection between a browser and an HTTP Server. Using SSL means that data (anything POSTed and any page content returned) is scrambled, not plain text.  This makes "sniffing" a phone line or wireless connection for sensitive data much more difficult. WebObjects can be (and has been) used with the HTTP secure socket layer (SSL) for secure transmission of sensitive data over the Internet. And all major E-Commerce sites powered by WebObjects utilize SSL.

From a WebObjects standpoint most of the issues around using SSL aren't your problem. The system admins that maintain and install the web server software are the ones responsible.  All the WO developer needs to do is emit the right kind of URL in generated pages to force access to certain pages through SSL. Unfortunately in WebObjects this can be a little tricky.  WO generates by default partial URLs. URLs like this:
    href="/cgi-bin/WebObjects/DESTest.woa/wo/F00000RN400aE1001/1.2"
When you click on a link with such an HREF, the browser constructs an absolute URL by prepending the a hostname and TCP protocol to this partial URL.  So if you want the link above to be accessed over SSL, you would have had to access the page this URL sits on via a secure page. But what if you came into the app on a non-secure URL? If you got to the page via http://, then you would need an absolute URL such as:
   https://myhost/cgi-bin/WebObjects/DESTest.woa/wo/F00000RN400aE1001/0.2
This means that unless you can guarantee having all pages in your site accessed via secure pages, you need your application to generate full URLs including https:// at some point instead of partial URLs.  There are many different ways to achieve this. One is to patch how WOContext generates URLs. This scheme is discussed in an existing WebObjects TIL: http://til.info.apple.com/techinfo.nsf/artnum/n70101.  This TIL also discusses a reusable component to control how the URLs are generated on a sub-page granularity. For example you might want some links to be normal and others secure.
    Another solution is to create custom versions of WOForm and WOHyperlink (among other elements) that construct their HREFs in a custom fashion.  The main problem with the TIL solution is that it only works because of the existence of a private Objective-C call (which means the solution is not directly accessible in Java).  However, the custom component route works for any language but is a bit intrusive in that suddenly you are using two different components throughout your app instead of dealing with just one for the same basic role. 
    Yet another solution involves HTTP redirection and works in Java as well as Objective-C (no private API)  and lets you use the standard elements instead of custom versions. In this method, you toggle your pages from secure to non-secure mode via a setting on the Session. If you are in secure mode and need to be in non-secure mode based on this setting, a page generation results in a redirection. If you are already in the right mode no redirect occurs. 
    One caveat with any form of secure URL toggling is that you should never transform from one mode to the other on the same page. If you do, you leave open the possibility for the user to change modes, but backtrack to an insecure version of a page, and submit private info in the clear from that page. 

Encryption

In addition to the SSL protocol, you might want to perform encryption programmatically.  Encryption might be embedded in business objects to automatically encrypt values on database writes and decrypted just-in-time on reads. You might implement this sort of behavior in custom accessor methods.  Some very security anal organizations will want everything encrypted that sits in a repository like a database.  Most will only be concerned about encrypting specific pieces of information. For example, you might want to store your Customer information in the clear except for just their credit card numbers and their password.

To encrypt specific information programmatically before storing it in a file system or database, WebObjects developers may take advantage any C or Java package for performing encryption.  The UFC-Crypt framework is an object-oriented wrapper around public domain C code implementing the UFC-crypt algorithm. This is not high grade encryption. For serious encryption you would want to use BSAFE (C) or JSAFE (Java) from RSA or similar packages from others.  These can be expensive and there are export restrictions to worry about.

So if you are going to encrypt a resource, what key size should you use?  You've probably heard that given enough computing power, nothing is truly secure. However, baring mathematical breakthroughs, something encrypted with a 1024 bit key would be impractical to break for all but large governments. There is also this perception that as time goes on things get easier to break. This is true given a constant key size. However as computing power goes up it also becomes practical to use larger key sizes. And as it turns out doubling key size only requires double the power for the encryption, but many orders of magnitude more effort if you are doing an attack. Therefore, as long as you are boosting your key size, encryption gets better with improving computing power. 

Some questions:
   	What is a digital signature?
	What is a hash?
         What is the market for VeriSign vs Entrust?
         What was the deal with the NSA and DES?
         Why is the NSA the one govt agency that is a true BAMF?

Authentication

Aside from SSL, authentication is the next most common construction used to implement secure access to users.  It seems simple. User provides a couple strings and server sees if they are correct. However there are so many ways to accept credentials and credentials can take many different forms.  There are also an unlimited number of different ways to store credentials. Finally there are application access policies to consider. Does a user have to login to get any access at all or just at certain stages in an operation or at certain places in the site?  Should you guard against multiple access attempts?  Should you allow users to surf your site and only popup a login panel on demand? Or should you just present an access denied message with a link to a login screen?  And on a more practical note, how can you implement login panels in WebObjects that do not require the creation of a session?  And if a session timesout, how can you make the timeout event direct the user immediately to a login page?  

There are two parts to authentication:  
     - Are you whom you say you are. And if so, 
     - do you have access. 
Or you can ask the questions in the other order: do you have access, and if so are you whom you say you are. The granularity of that access after initially granted is the domain of authorization algorithms like access control lists, discretionary access control mechanisms, and so forth.  Authorization or access control is the subject of another section below.  

In addition to the two logical phases of authentication, there are at least two physical phases as well. One is gathering the credentials. The other is processing these credentials.  Unfortunately it is easy to tie these two roles together in ways that prevent reuse.  Gathering credentials is very presentation specific. However validating the credentials is really a business logic operation. This is the part where your code will often query a data repository of some kind such as an Oracle RDBMS, an LDAP directory, or even an ERP application.

To help make creating authentication policies easier and to implement some common authentication functions, I pulled in code and advice from others as well as personal experience to create the WXAuthenticationPolicy.framework.  This framework includes support for HTML login pages, HTTP 1.0/1.1 authentication panels, digital IDs, access policy, on-demand login, sessionless login attempt support, and login tracking statistics among other features.

HTML LoginPage

This is the easiest way to authenticate in a WOApp. There are two annoying side effects to this though.  You normally appear to need to kick off a session to make the login attempt. Sessions can be heavy weight and you might not want to create one if the user isn't authenticated.  Also if you logged in previously and your session logs out, it is often inconvenient to be forced to deal with a session expired page.  You may want your user's to be taken straight to the login page.  The WXAuthenticationPolicy.framework includes code for doing stateless logins as well as as session expiration responses that vector to the login page.

HTTP Challenge Authentication

This form of gathering username/password is driven by emitting certain kinds of headers and statuses in a WOResponse. It also involves decoding the data from the incoming challenge panel submission. The WXAuthenticationPolicy.framework includes code that performs these translations and knows how to emit and respond to HTTP challenges.  One thing tricky about HTTP challenge is that the different web servers out there tend to work with it slightly differently.  For example, Netscape servers do not pass the "authorization" header to your application which means you can generate the panel, but not process its response. With Netscape servers, you have to use the NSAPI interface to get this header. There are also special caveats for IIS. A WO technote accessible via the WOInfoCenter discusses HTTP challenge authentication in great detail.

Access Blocking

There are many different ways to access resources in a WOApp. Often this is a great feature. A URL such as this:
    http://myHost/cgi-bin/WebObjects/WOInfoCenter
by default takes you to the "Main" page. Then there are the DirectAction URLs that can take you just about anywhere in an application. You may not want to grant such access unless a user has been authenticated first.  Two key choke points to guard in your application are:
     public WOElement invokeAction( WORequest aRequest, WOContext aContext)
     public void appendToResponse( WOResponse aResponse, WOContext aContext)
There are versions of these methods in your pages, session, and application. The versions in WOApplication are the best versions to override as these are called before any of the others.  Your logic should check your authentication test and only invoke super if the test is passed.  By overriding invokeAction() you prevent unauthorized ComponentActions from being invoked.  By overriding appendToResponse you prevent unauthorized pages from being generated even if the actions that led to their return were authorized for execution.  

If you want to shutdown all your DirectActions unless they pass your test, you will want to override WODirectAction's:
    public WOActionResults performActionNamed(String anActionName)
If your test fails, you can create your login page instead of calling super. Note that if you have multiple WODirectAction subclasses, you will have to implement this method in all of them. You should probably ensure that all of your subclasses inherit from your own abstract subclass of WODirectAction so this security shielding code can exist in one place.

On Demand Login

Sometimes you want to permit a user to create a session and/or access direct actions to their hearts content, but at the same time you have resources that nevertheless need to be protected.  Now you could hide links to such pages unless the users are logged in using WOConditionals.  But it's often more convenient to let the user click on a link even if they aren't authorized to see the destination. Instead of taking them to the page, you want to popup an authentication page or panel. And if the authorization succeeds you want to take them directly to the page in question. Any other secure pages will now allow the user to proceed without further authentication requests.

If we're talking about purely navigation links, then the actions that transition to the destination pages don't do irreversible processing. In other words, it is probably OK to execute the direct action or component action in most cases. In these cases, you only need to override 
     public void appendToResponse( WOResponse aResponse, WOContext aContext)
The best place to cover all the bases is to override this method on WOApplication. Before you allow the call to super, you perform your test, and if it fails, you return your LoginPage. But before you return it, you set some state in the returned page or the session indicating the page name of the intended destination. Then if the login succeeds, your login action can use this state to take the user directly to where they originally wanted to go.

If you also need to prevent actions from invoking, then you also override invokeAction and performActionNamed as described in the 'Access Blocking' section above. But instead of hard coding the destination of the login action, you store the destination page name if possible. However since in these methods you are intercepting the behavior before the actual return page is being generated you will not be able to guarantee knowing what the destination page is so you may have to make 'this' page the destination (refresh the screen) as a default behavior.  Since a DirectAction may have enough info encoded in its URL to determine the intended destination, you may be able to go directly there after login. However this will be completely application specific.

Sessionless Login

To prevent a session from automatically being created the moment a user contacts your app, you should add this line to your Application constructor:
     setDefaultRequestHandler(requestHandlerForKey(WOApplication.directActionRequestHandlerKey()));
Now when users contact your app, the defaultAction method on your WODirectAction subclass will fire and no session will be created. Your version of defaultAction() should return your version of a LoginPage. Furthermore, the method invoked on the LoginPage (when a user submits their username/password) should be a DirectAction as well.  Take care not to create a session as a side-effect. Never call session() in your login action. This will create a session if it doesn't already exist.  If you sometimes want to use session data if a session is active, then be sure to use WOContext's hasSession() method to check for its existence first. One nasty thing to look out for is the use of session() in components your login page uses. If any component or subcomponent of a subcomponent uses this method, a session will be created.

Tracking Login Attempts

If you are using a username/password authentication scheme then you probably want to ensure that users can't just keep trying to guess someone else's password over and over again. This kind of countermeasure really amounts to a kind of intrusion protection covered in the following section but its implementation is so closely tied to username/password login, we discuss it here.

Tracking means keeping a list of access attempts for some interval and grouping these access attempts by various criteria such as IP address of origin and username. For example, you might want to lockout access from a particular IP address if you detect that more than 4 attempts at access have failed in the last 5 minutes. Or you might lockout a particular account if multiple failed attempts occur in a certain interval regardless of the origin.

Now using IP addresses can be dangerous because they can be spoofed or more commonly they can simply be shared across a large number of users (such as with AOL users). An attacker might be trying to attack many different usernames from many different (seemingly) IP addresses. Or in the case of AOL, you might be getting thousands of access attempts from the same IP address but in this case it does not represent an attack. One way to combat this IP address float is to emit a cookie.  You can check the cookie on subsequent access attempts and tell how many accesses you have received from a given desktop.  Your policy might dictate to a customer that they enable cookies in order to be granted access. 

Digital Certificates

The ultimate mechanism for authentication is the digital certificate.  All other forms of authentication require the secure storage of a private token on the server.  A digital ID however requires no server side password. If you are using SSL as the means of exchanging digital IDs, then this protocol verifies the user is whom he claims to be first. In order to pass this test, your web server must have been configured to trust the CA that issued the certificate of the client.  Also, you must configure your web server to request SSL client authentication.

Once this SSL test is passed, the certificate may be processed by your application to determine if the user has access to the system.  This is analogous to checking a password first and then seeing if there is a user matching the username.  The equivalent of the username in this case is the contents of one or more fields in the digital certificate. Or the physical certificate itself. Many companies store digital certificates of employees and trading partners in LDAP directories.  Although not as common yet as it should be, a server should check the revocation status of a certificate before it accepts the ID as good. This can be done by downloading the latest version of the CRL or by consulting a Validation Authority (VA) server which aggregates information from many CAs.

Digital IDs have two parts: the private key (which never leaves the client) and the public certificate. Usually the private key is stored in an encrypted file on a user's computer. Companies like GemPlus and Schlumberger make smart cards that have the private key embedded in a tamper proof, and portable fashion.  You can take the card with you just like a driver's license.  In order to unlock the use of the digital ID, a user must enter a pass phrase.  You need the pass phrase because you don't want to store your private key in the clear (if you are storing it in a file) and you don't want some stranger (who happens to have access to your machine while you get a cup of coffee) to be able to start impersonating you digitally.

Unlike username/password authentication, this pass phrase never leaves the client machine. Nevertheless in many ways this is a weak point in public key crypto. Afterall ultimately it doesn't do much good to have a 2048 bit key when the pass phrase to unlock it is "foobar".  Even if you protect your private key in a smart card, you are susceptible to this weakness. This is changing.  Highly security conscious organizations can use special smart cards and PC card devices where the passphrase isn't text but instead it's a biometric characteristic about you such as your voice, your face, your thumbprint, handprint, or retina scan. For portability, thumbprint and voice are the most common for now.  This is pretty serious security. To impersonate you digitally (to digitally sign, access resources, perform transactions, or decrypt your data), someone would have to steal your smart card and some part of your body.  The implications, of course, for the truly desperate attacker are somewhat gruesome.

Now for the most part you could implement authentication via digital certificates entirely within the realm of your server's HTTP server. However there will certainly be times when you will want your application code to have access to the certificate passed in from the client.  Unfortunately the WebObjects adaptors either don't pass the certificate header along at all or pass it on in a truncated form.  The WOSecurityKit includes source and a pair of pre-built binaries for a CGI and NSAPI WOAdaptor that correctly pass these certificates from web server to app.  The certificate comes in under the header key "CLIENT_CERT" as a base64 string encoding of an ASN.1 data structure. Once you have this string you will want to parse it into useful data.  In Java you may wish to use the java.security package which comes built into the 1.1.x JDK.  If you are using C code you might use the SSLeay source code.

Intrusion Protection

This is the purview of the traditional systems hacker.  It describes how developers and system administrators can reduce breaches of security. 

WebObjects works with commercial firewalls and firewall topologies, such as DMZ subnets and router solutions.  Some firewall products have been specifically developed to enhance the features of WebObjects, such as HP's VirtualVault line of HPUX servers.  WebObjects by its nature protects corporate business logic and data services by placing multiple layers of access machinery between it and the outside world.  For example, WebObjects makes it easy to separate sensitive from non-sensitive business logic, thus allowing developers to strike the right balance between client-side and server-side logic. 

There are many different ingredients to protection in WebObjects applications. Some examples of elements used to enforce protection, from the browser all the way into the database, are included below.

Session ID and information hiding

Hiding session information, such as a session ID or Kerberos ticket, prevents a passer-by from copying and obtaining access to a user's session information from the screen.  Developers can hide session information via support in WebObjects for cookie storage.  Note that by default no WOSession information, other than the Session ID, is ever transported over the Internet to and from the Application Server. This keeps a user's session much more secure than solutions that require such state to be stored in the browser client.

Firewall and HTTP Server integration 

WebObjects typically works unmodified to take advantage of basic firewall and server access rules (like disallowing FTP access, or only allowing access from certain IP addresses).  Any network elements, such as routers, computer firewalls, or secure subnets (known as DMZs), work well with WebObjects.  By design, web clients do not make direct connections or use non-standard transports to WebObjects application servers in a deployment mode; WebObjects has an adaptor module that runs behind standard web servers.  Instead, clients interact with a WebObjects server via the web server(s) just like any other web requests. 

Since WebObjects just works with the most common, tested web servers on the market, it can piggyback on any advances made that make user to business and business to business links more secure. This may seem like a no brainer, but there are App Server products out there that require web clients to directly connect to the app.

WOAdaptor

WebObjects includes 5 flavors of HTTP server adaptors for CGI, NASPI, ISAPI, WAI, and Apache DSO interfaces.  All of the interfaces share a common library of code for communication with WebObjects application servers.  Using the provided source code, it is possible to customize WOAdaptors to perform additional processing, such as examining for a security token (which can be set by WebObjects or another authentication mechanism). Your WOAdaptor would then operate at the granularity of your site's WOApps.

WOApplication

WOApplication implements methods that are invoked at every phase in the request handling process, which is useful for enforcing globally scoped rules.  Developers are expected to subclass WOApplication into a subclass of their own, which can be used to override hooks in the system for added functionality. Among others, these hooks include: 
	
	awake() - which is called before any thing else
	takeValuesFromRequest() - which is called during request value extraction
	invokeActionForRequest() - which is called during action invocation
	appendToResponse() - which is called during page response construction
	sleep() - which is called at the end of the the request handling process

If an application developer wanted every single request into the app to pass a test, this test could be placed into the awake() method of the WOApplication subclass.

WOSession

Like the WOApplication class, developers are expected to subclass WOSession, which can be used for enforcing session scoped rules based on user specific state.  Like WOApplication, WOSession implements methods that get invoked on your code at every phase of the request handling process. Instead of operating on global set of data manipulated by an Administrator, a WOSession subclass acts on data scoped to a user.  To make sure it is impossible for a user to access certain pages for example, a developer might put a rule in the session's version of invokeActionForRequest() to only permit access under certain circumstances.

WOComponent

WOComponent defines behavior for a page or parts of a page.  As with WOApplication and WOSession, WOComponent is subclassed by developers and implements all the same request handling methods, thus individual pages can embed protection rules.  These rules might allow the page to display itself in several different ways depending on page-based state and the combination of the current application and session state.  The page in turn can use WOConditional objects to control what can or cannot be seen.

Java Clients

JavaScript or applet code embedded into a page is wide open to inspection a security consideration that seems to rarely come up. (JavaScript is already in ASCII readable form).  Java (even though it can be obfuscated) can be de-compiled (using free tools), read, and copied.  Therefore any Java class file that arrives in a browser is code you have exposed.  

Some Java client architectures make direct connections back to a database server or to a facility that pools database connections but without any further restrictions (e.g. DBAnywhere).  This scenario is perfect for an enterprising hacker to extract database login information right from the source code to your Java applet.  In WebObjects, Java clients do not talk directly to any back-end system.  Java clients are restricted to accessing systems through logic in the Application server, your Application subclass, your Session subclass.  Only those classes, in turn, have access to back-end resources such as mainframes, ERP systems, and Oracle databases.  

The EOJavaClient kits in WebObjects let you create Java client web applications that split business logic into client side and server side versions. The client version of the business object can have fewer attributes and implement different logic than the server-side version.  Thus an app can enforce all logic but keep the sensitive rules and data on the server and still give the user immediate feedback from less mission critical validation rules on the client.

EOF delegation

Delegation within the Enterprise Object Framework layer makes it possible to globally intervene on any attempted database operation before it happens.  Virtually everything a WebObjects application does during the processes of creating, deleting, updating, and fetching objects can be intervened upon using 'delegation' hooks, a form of callback. Furthermore when important events happen, EOF posts notifications which might be used for auditing purposes.

A developer can use these hooks to establish pervasive rules limiting the interaction with the back-end. For example, the delegate hooks on the EOAdaptor layer can restrict what tables can be updated, put an upper limit on the maximum number of rows allowed to be returned, or inspect the raw SQL generated before it is actually sent to the server.

Access

With EOF, you can centrally control what people see based on who they are and what they are looking at. In my experience, the basic Access methods I use are the canShow and canEdit.  They are questions presentation level code can ask to decide when and what to show and allow.  I begin by creating a generic EO superclass that implements basic canShow, canEdit methods that most objects being secured would use.  Subclass EOs can then provide their own implementations. 

One example of a good inheritance chain is:

GenericEO
	SecuredEO
		Product

Where GenericEO and SecuredEO are abstract classes. And Product is a class mapping to a Table.

Every EO might inherit from GenericEO.  The implementations of canShow and canEdit here would be:

public boolean canShow(User aUser){
   return true;
}
public boolean canEdit(User aUser){
   return true;
}

Notice how these methods take another object (a User EO) as an argument.  So I'm dictating some schema here in that I assume you have a User Entity in your EOModel.

Now SecuredEO might look like this:

public boolean canShow(User aUser){
   if(aUser.equals(creator()))
       return true;
   else if(owners().containsObject(aUser))
       return true;
   return false;
}
public boolean canEdit(User aUser){
   return canShow(aUser);
}

Subclasses of SecuredEO clearly are expected to have certain schema based on these implementations. In my example here, I assume all such EOs have a to-one relationship that returns the User EO for the creator of the object. I also assume there is a to-many relationship holding the owners of the object.  The logic means that if the User passed is either the creator, or an owner, then it can be shown.  And what can be shown can be edited.

Now lets look at a sample implementation of the canShow() rule for the Product EO:

public boolean canShow(User aUser){
   if(super.canShow(aUser)) return true;
   /* 
	Some arbitrary rule
   */
   return false;
}

In this case, if the superclass rule holds, you can see it.  If not, some other rule kicks in. If that fails, you shouldn't see it.

A more interesting policy might dictate that all SecuredEOs have a to-one relationship to a entity describing permissions.  To mimic Unix file permissions, your Permission table might describe the combinations of what was and wasn't allowed: for example this table might hold columns representing show/edit rules for creators, owners, groups. This kind of access is called Discretionary Access Control (DAC).

If you wanted to use a more stringent policy then you might want to implement one based on Mandatory Access Control (MAC). In MAC, your Permission table might have simple access levels like: "Top Secret", "Secret", "Confidential", and "Unclassified". MAC also requires something called Compartments (which is like a Unix Group).  Examples of entries in a Compartment table might be: "Accounting", "Sales", "Marketing", etc.  For more on DAC and MAC see the O'Reiley book "Computer Security Basics".  Whatever the access control method, you can handle it within your implementation of your canShow and canEdit methods.  Indeed even if your access strategy changes significantly (assuming you centralize your policy within EOs in this fashion), consumers of your EOs may not need to change a line of code.

On the presentation side, WebObjects includes support for objects such as WOConditionals that can be used to show or hide parts of the user interface based on the yes/no answers EOs give to the canShow/canEdit questions made of them. 

Integrity

Integrity means that the application must not corrupt information or be fooled into using improperly modified data.  If you can mathematically prove that a transaction happened and that only the parties involved could have agreed to the transaction, then you have something known as nonrepudiation. In the physical world you achieve this typically through hand written signatures on a document. Of course the idea is that a signature binds to a piece a paper (freezing the relationship between content and authorization) and that such signatures are difficult to forge. After the fact, one of the parties might disavow the transaction. But if you have a record of his signature on it, you have a strong element of nonrepudiation to prove your case to a third party.

Using digital certificates you can achive in some ways a stronger degree of nonrepudiation in fully electronic B2B and B2C transactions than you ever could for ink signatures. To get such nonrepudiation in a B2C dialog, your clients need to have their own digital certificate.  If the client and server are in the same company and the users are employees filling out company forms on the wbe, then the liklihood of having users with client certificates is good. 

A vendor called Celo has created a plugin for Netscape and IE browsers that can digitally sign a BLOB of data. The way it works is like this:  
    - The user fills out an HTML form and submits it.
    - The WOApp processes the action and generates a document that summarizes what the user typed in
    - The WOApp returns a page that has the Celo plugin in it via the EMBED tag.  
    - The "src" attribute of the plugin then retreives your document as a BLOB of data
    - Once the data has been retreived, the plugin enables some controls that let the user select the digital certificate to use for signing and prompts the user for their passphrase. 
    - After signing, the plugin submits the signed BLOB back to the WOApp 

For an example of a place where digital signatures would come in handy in a common e-commerce application, consider the B2B scenario involving DropShipping. Imagine you are a WOApp processing orders for Jim's Bike Shop (JBS).  An order from Anna comes in for a bike and a water bottle.  You have the Bike in inventory but not the bottle because you are allowed to dropship the bottle... That is, Paul's Water Bottle's Inc. (PWB), your supplier will ship the bottle directly to your customers.  This is great for JBS (one less thing to manage in the warehouse), but PWB needs to be sure that orders to ship product (such as Anna's) are the real deal. And in the event JBS decides to disavow the order, well, PWB would like to have some proof that will last that says indeed JBS did make the order.  The way this typically works today for most businesses (even the so called dot com merchants) is for JBS to print a dropship purchase order.  Someone with authority at JBS then signs this paper with ink and then (ug) Faxes it to PWB.  PWB receives the order, someone there looks at the order document, its signature, and letterhead/format. If it all looks good, they ship the product.  

What's sad about POs in general and DropShips in particular is that you have this computer based order taking, processing, and fulfillment system. You might have paid millions for it, and yet just because you want to DropShip one item in an order, that whole Order (which otherwise would have generated no paper at all) has to wait for humans to print documents, feed Fax machines, and file receipts.

Now if you are Ford Motor Co. then you have built a value added network (VAN) that all your suppliers participate in. It costs a million or so each month to operate, but it lets Ford do EDI over this network. So at least the PO can stay in electronic form from Ford's perspective. However for many EDI players, EDI is basically a glorified FAX machine. Often the poorer partners end up keying everything into a terminal so things aren't purely electronic. And there is still a lack of nonrepudiation even in the fully electronic cases unless the parties embed digital signatures in their EDI documents. 

Machine to Machine Communication

WO4.0.1's DirectAction feature made it easier to listen to HTTP requests created by remote machines. But it was still hard to create HTTP requests in your code. In WO4.5, this changes. You can create and send WORequests and listen for their WOResponses in code without having to become an expert in sockets programming. Furthermore industry standards are cropping up to define XML documents (instead of EDI documents) that define all kinds of different transaction types. And as it turns out, WO4.5 has a lot of new XML generation and parsing support. So now the low level support is there to do some pretty interesting server-to-server communication. You can turn this into a secure channel for authentic, nonrepudiable B2B communication by combining these new features with public key cryptography. With such a combination, no more paper is required for a whole class of business processes (except for optional offline file storage). 

However note that even in a purely electronic world, there still will most likely be a person involved if the stakes are high enough. The person might be an officer of the company that approves digital transactions before they are allowed to proceed. Machines might use email, electronic paging, or more elaborate means to get a queue of orders in front of such an officer. To prove to PWB that the order is real, JBS (or an officer at JBS) digitally signs its DropShip order. To make sure only PWB can read the order, JBS encrypts it with PWB's public key. Likewise, PWB (or an officer at PWB) digitally sings the response it sends back to JBS and encrypts it using JBS's public key.  The content actually returned by PWB to JBS would be the equivalent of a "digital receipt" of the execution of the dropship. 

From a WO perspective, the digitally signed, encrypted content sent is a BLOB that gets POSTed to a URL for the target web application.  If the destination app is a WOApp, this URL will be for a DirectAction.  On the receiving end, if you are a WOApp creating a response, you generate a "page" as normal except this time the page contains a BLOB (perhaps encoded using Base64 text).  Note, instead of encrypting the BLOBs explicitly, you might just communicate over HTTPS instead of HTTP.

Also there are many other ways of performing this communication. JBS and PWB might do it all in one transaction (as described above). Or (more likely) JBS might send a request and get just an acknowledgement in response from PWB: Something like: "I got it; processing now...". And then JBS would wait to receive the results of the transaction. In other words, JBS would also be listening like a server but for a transaction result instead of a transaction initiation. When PWB was through processing the original DropShip order, it would create its own WORequest and POST its results to JBS. These results would ideally contain the digital receipt.

In another form of communication, JBS and PWB might use a trusted third party to host their documents. JBS and PWB both POST or simply FTP their documents to a central server. They both are responsible contractually to check this central server for documents as well.  The document hosting service would be responsible for making sure the service was available and might even assume liability if it lost a document for which it had confirmed receipt.  Basically what I'm describing is a VAN. A VAN using the Internet, XML, HTTP, and cryptography instead of leased lines, EDI, and EDI formatted documents. There are already companies that provide such services.

As in the authentication example, when using digital credentials it is always important to validate before execution of an event.  If you operate your own CA and all your trading partners use you as the CA, then you have all the revocation information data needed to validate credentials. However odds are you won't be the CA because if someone is going to get their digital PassPort they are going to get it from their company or from a third party like VeriSign or Entrust.net. To validate credentials from any source, you should make a query against a Validation Authority (VA). A VA can return a proof that the certificate used to sign a document was in fact good at the time it was used. Thus even if the certificate is revoked later or expires, the document being signed is still valid.

When you create your digital receipt, it would be ideal if the receipt were stored in a public place where both parties can access the information.  The XML definition of a digital receipt has been standardized in terms of its "envelope" and in terms of specific content for a growing list of industries like retail.  And there are already companies (such as ValiCert) that will notarize (digitally sign as a trusted third party), digitally timestamp, store, and provide web access for these receipt documents from tamper-resistent databases within bunkered data centers. 

Some questions:
	What is a CA?
	What is a digital timestamp?
	How do I know this cert is for the REAL John Doe?
	What is a VA?
	What is a digital receipt?

EXTRA FROM EMAIL MESSAGE FROM THE AUTHOR:

I'd like to make some special case corrections to some of the comments
in the white paper...  

To REALLY protect page generation in ALL cases, you need to override
appendToResponse on WOComponent.  WOApplication's version will work in
most cases... however if the VERY first page of the app is protected,
the appendToResponse on WOApp won't get called, but the one on
WOComponent of course always will; therefore, in this case you will want
to guard WOComponent's appendToResponse.

I said that if you are in a direct action and want to test for a
session's existence you should use WOContext's hasSession().  Actually
this might be true when a direct action is generating its response (or
if you have created a page within an action), but not the best thing to
use while in a DA. You should use WODirectAction's existingSession call.

I also mentioned that smartcards with biometric passphrases are the best
way to protect your personal cert's private key... I would add that
using a biometric AND a passphrase would be better... in case someone
digitized your thumbprint and fooled the thermal circuit on the reader
(such as Sony's).  Your biometric is kind of like a public passphrase.
You should probably always have at least something in your head as a
supplement to it. One company combines PIN, biometric, AND SecureID as
required input for authentication.