The following example illustrates
how application programs can perform a programmatic login using Java Authentication
and Authorization Service (JAAS):
LoginContext lc = null; Subject subject = null; try { lc = new LoginContext("WSLogin", new WSCallbackHandlerImpl("userName", "password")); } catch (LoginException le) { System.out.println("Cannot create LoginContext. " + le.getMessage()); // Insert the error processing code } catch(SecurityException se) { // Insert the error processing code } try { lc.login(); subject = lc.getSubject(); // setting the subject on the thread to use for outbound requests. // Note: This overrides the existing subject which you might want to save first. com.ibm.websphere.security.auth.WSSubject.setRunAsSubject(subject); } catch(LoginException le) { System.out.println("Fails to create Subject. " + le.getMessage()); // Insert the error processing code }
As shown in the example,
the new LoginContext is initialized with the WSLogin login configuration
and the WSCallbackHandlerImpl CallbackHandler. Use the WSCallbackHandlerImpl instance
on a server-side application where prompting is not desirable. A WSCallbackHandlerImpl instance
is initialized by the specified user ID and password information. The present WSLoginModuleImpl class
implementation that is specified by WSLogin can only retrieve authentication
information from the specified CallbackHandler. You can construct
a LoginContext with a Subject object, but the Subject is disregarded
by the present WSLoginModuleImpl implementation. For product client
container applications, replace WSLogin by ClientContainer login
configuration, which specifies the WSClientLoginModuleImpl implementation
that is tailored for client container requirements.
For a pure Java application
client, the product provides two other CallbackHandler implementations: WSStdinCallbackHandlerImpl and WSGUICallbackHandlerImpl, which prompt for user ID and password information on the command line and
pop-up panel, respectively. You can choose either of these product CallbackHandler implementations
depending on the particular application environment. You can develop a new CallbackHandler if
neither of these implementations fit your particular application requirement.
You also can develop your own LoginModule if the default WSLoginModuleImpl implementation fails to meet all your requirements. This product provides utility functions that the custom LoginModule can use, which are described in the next section.
In cases where there is
no java.naming.provider.url set as a system property or in the jndi.properties file,
a default InitialContext does not function if the product server
is not at the localhost:2809 location. In this situation, perform
a new InitialContext programmatically ahead of the JAAS login. JAAS
needs to know where the SecurityServer resides to verify that the user ID
or password entered is correct, prior to doing a commit(). By performing a
new InitialContext in the way specified below, the security code
has the information needed to find the SecurityServer location.
Note: The first line starting with env.put was split into two lines because it extends beyond the width of the printed page.
... import java.util.Hashtable; import javax.naming.Context; import javax.naming.InitialContext; ... // Perform an InitialContext and default lookup prior to logging in so that // bootstrap host/port can be determined for SecurityServer lookup. Hashtable env = new Hashtable(); env.put(Context.INITIAL_CONTEXT_FACTORY, "com.ibm.websphere.naming.WsnInitialContextFactory"); env.put(Context.PROVIDER_URL, "corbaloc:iiop:myhost.mycompany.com:2809"); Context initialContext = new InitialContext(env); Object obj = initialContext.lookup(""); LoginContext lc = null; try { lc = new LoginContext("WSLogin", new WSCallbackHandlerImpl("userName", "password")); } catch (LoginException le) { System.out.println("Cannot create LoginContext. " + le.getMessage()); // insert error processing code } catch(SecurityException se) { System.out.printlin("Cannot create LoginContext." + se.getMessage(); // Insert error processing } try { lc.login(); } catch(LoginException le) { System.out.printlin("Fails to create Subject. " + le.getMessage()); // Insert error processing code }