Java Security Programming Interfaces


J2EE draws the majority of its security-related programming interfaces from other standard Java extensions and the core Java 2 Security service. The Java 2 Security model introduces the idea of a security manager, security permissions, and the JAAS programming interfaces. We will discuss these in this section.

Java 2 Security

This book is not intended to be a primer on the Java 2 Security model. However, a few aspects of the Java 2 Security programming model are worth highlighting as they are supported in the WebSphere hosting environment.

Principals and Subjects

When WebSphere authenticates a user (or any other entity), it creates a Principal object representing that user's authenticity. You can get the authenticated Principal associated with a request with the getUserPrincipal() or getCallerPrincipal() method.

In fact, this Principal is actually associated with a JAAS Subject, although there are no interfaces for getting a Subject from a Principal. The Principal represents the user's authenticity within a particular authentication domain. The Subject represents the user in a more general form – independent of any particular authentication domain. In theory, the same Subject may be authenticated in multiple authentication domains concurrently in which case the Subject will have several Principals – one for each authentication domain.

If you log a user in programmatically through JAAS, using a javax.security.auth.login.LoginContext, you can then get from that LoginContext the Subject that logged-in, and from that any Principals that were formed for each of the authentication domains configured to the system.

Java 2 Security Manager

WebSphere uses the Java 2 Security Manager to enforce code-set authorization policies – that is, authorization policies that establish what a Java class is allowed to do. The Java 2 Security Manager operates on the principle of least-privilege. This principle requires that a user be given no more privilege than necessary to perform a job. Said a different way, you can only do what the least of the code can do in your context. This is a recursive property that eventually leads to testing the entire code stack on a particular thread of execution. Every piece of code in the call stack must have been granted a permission for any of the code at the top of that stack to perform something that requires permission. So, for example, if you want to read a file in your program, everything that leads to the calling of that program requires you to have permissions.

The purpose of this principle is to keep code that calls your program from gaining access to information and resources that you have, and that the code would itself be denied access to. While this is noble, and in fact critical to maintaining system integrity, it can also be an obstacle. If you offer a service that is designed to perform a particular function, but you require permission to, for example, read a file to accomplish that function, then obviously you will be prevented from performing your function unless the code that calls your service has the permissions that you need.

Java 2 Security offers a way around this problem. Within your program, you can perform a doPrivileged() call on a java.security.AccessController, passing in the PrivilegedAction object that you want to execute. The PrivilegedAction object must implement the run() operation. The AccessController will effectively create a new execution frame on your call stack and then invoke your run() operation. The PrivilegedAction will then be evaluated in that new execution frame – as though it is executing on a new thread. This can get a little complicated as it essentially requires an additional class for every segment of code that you want to run in this privileged mode. Moreover, the PrivilegedAction you introduce also must be granted the permission that your normal class would have – it is now acting as your surrogate.

If you use the doPrivileged() operation you are assuming the responsibility for ensuring you don't allow protected information or other resources and actions to be siphoned back to your callers. Consequently, you should use this operation with extreme care. WebSphere makes substantial use of doPrivileged() in its runtime to ensure it can continue to operate correctly even if your application hasn't been granted all of the permissions that it needs to do its job.

More importantly, WebSphere forces a doPriviledged() operation in the call path between EJBs if you make a call between the remote interfaces of EJBs installed in the same application server instance. This is to emulate local-remote transparency. Since the call stack is not transferred between servers, remote EJBs have the built-in equivalent of a doPrivileged(). If you write a call to another object in a different server instance, that same call may not work if you relocate that target object to the local server. WebSphere initiates the same doPrivileged() between container breaches to help emulate a remote call.

JAAS

The JAAS interfaces can be used to authenticate a new user. This can be used in a couple of different ways. If you simply know that you want to authenticate a real end-user presuming your application is running in a client or somewhere in the vicinity of a real end user, you can use the WebSphere provided LoginModule() and initiate a login by creating a default LoginContext().

If you need to do anything more creative – like authenticating a user based on information they supply to you through a set of arguments to a component that you've implemented – then you will have to implement your own LoginModule and initialize that in your LoginContext. This is done through the standard JAAS interfaces so we won't cover those specifics here.

When a principal is authenticated and a Subject and corresponding Principal object are formed by WebSphere, it will associate that Subject with the execution context for your application. However, when you authenticate a user in your application code, the Subject is formed but is not automatically associated with the execution context. However, you can accomplish the same thing by invoking the doAs() static operation on the javax.security.auth.Subject object. This has the effect of associating the specified Subject with the execution context – the programmatic equivalent of the RunAs() deployment descriptor. The Subject associated with the execution context will be used for any down stream requests embodied with the doAs() execution block.




Professional IBM WebSphere 5. 0 Applicationa Server
Professional IBM WebSphere 5. 0 Applicationa Server
ISBN: N/A
EAN: N/A
Year: 2001
Pages: 135

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net