Programmatic login is a type of form login that supports application presentation site-specific login forms for the purpose of authentication.
When enterprise bean client applications require the user to provide identifying information, the writer of the application must collect that information and authenticate the user. You can broadly classify the work of the programmer in terms of where the actual user authentication is performed:
Users of Web applications can receive prompts for authentication data in many ways. The <login-config> element in the Web application deployment descriptor file defines the mechanism used to collect this information. Programmers who want to customize login procedures, rather than relying on general purpose devices like a 401 dialog window in a browser, can use a form-based login to provide an application-specific HTML form for collecting login information.
No authentication occurs unless global security is enabled. If you want to use form-based login for Web applications, you must specify FORM in the auth-method tag of the <login-config> element in the deployment descriptor of each Web application.
Applications can present site-specific login forms by using the WebSphere Application Server form-login type. The Java 2 Platform, Enterprise Edition (J2EE) specification defines form login as one of the authentication methods for Web applications. WebSphere Application Server provides a form-logout mechanism.
Java Authentication and Authorization Service programmatic login
Java Authentication and Authorization Service (JAAS) is a new feature in WebSphere Application Server. It is also mandated by the J2EE 1.3 Specification. JAAS is a collection of strategic authentication application programming interfaces (API) that replace the Common Object Request Broker Architecture (CORBA) programmatic login APIs. WebSphere Application Server provides some extensions to JAAS:
...
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.InitialContext;
...
// Perform an InitialContext and default lookup prior to logging
// in to initialize ORB security and for the bootstrap host/port
// to be determined for SecurityServer lookup. If you do not want
// to validate the userid/password during the JAAS login, disable
// the com.ibm.CORBA.validateBasicAuth property in the
// sas.client.props file.
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("");
Finding the root cause login exception from a JAAS login
try
{
lc.login();
}
catch (LoginException le)
{
// drill down through the exceptions as they might cascade through the runtime
Throwable root_exception = determineCause(le);
// now you can use "root_exception" to compare to a particular exception type
// for example, if you have implemented a CustomUserRegistry type, you would
// know what to look for here.
}
/* Method used to drill down into the WSLoginFailedException to find the
"root cause" exception */
public Throwable determineCause(Throwable e)
{
Throwable root_exception = e, temp_exception = null;
// keep looping until there are no more embedded WSLoginFailedException or
// WSSecurityException exceptions
while (true)
{
if (e instanceof com.ibm.websphere.security.auth.WSLoginFailedException)
{
temp_exception = ((com.ibm.websphere.security.auth.WSLoginFailedException)
e).getCause();
}
else if (e instanceof com.ibm.websphere.security.WSSecurityException)
{
temp_exception = ((com.ibm.websphere.security.WSSecurityException)
e).getCause();
}
else if (e instanceof javax.naming.NamingException)
// check for Ldap embedded exception
{
temp_exception = ((javax.naming.NamingException)e).getRootCause();
}
else if (e instanceof your_custom_exception_here)
{
// your custom processing here, if necessary
}
else
{
// this exception is not one of the types we are looking for,
// lets return now, this is the root from the WebSphere
// Application Server perspective
return root_exception;
}
if (temp_exception != null)
{
// we have an exception, let's go back an see if this has another
// one embedded within it.
root_exception = temp_exception;
e = temp_exception;
continue;
}
else
{
// we finally have the root exception from this call path, this
// has to occur at some point
return root_exception;
}
}
}
Finding the root cause login exception from a Servlet filter
Throwable t = com.ibm.websphere.security.auth.WSSubject.getRootLoginException();
if (t != null)
t = determineCause(t);
Enabling root cause login exception propagation to pure Java clients
com.ibm.websphere.security.registry.propagateExceptionsToClient=true
Non-prompt programmatic login
javax.security.auth.login.LoginContext lc = null;
try {
lc = new javax.security.auth.login.LoginContext("WSLogin",
new com.ibm.websphere.security.auth.callback.WSCallbackHandlerImpl("user",
"securityrealm", "securedpassword"));
// create a LoginContext and specify a CallbackHandler implementation
// CallbackHandler implementation determine how authentication data is collected
// in this case, the authentication data is "push" to the authentication mechanism
// implemented by the LoginModule.
} catch (javax.security.auth.login.LoginException e) {
System.err.println("ERROR: failed to instantiate a LoginContext and the exception: "
+ e.getMessage());
e.printStackTrace();
// may be javax.security.auth.AuthPermission "createLoginContext" is not granted
// to the application, or the JAAS login configuration is not defined.
}
if (lc != null)
try {
lc.login(); // perform login
javax.security.auth.Subject s = lc.getSubject();
// get the authenticated subject
// Invoke a J2EE resource using the authenticated subject
com.ibm.websphere.security.auth.WSSubject.doAs(s,
new java.security.PrivilegedAction() {
public Object run() {
try {
bankAccount.deposit(100.00); // where bankAccount is a protected EJB
} catch (Exception e) {
System.out.println("ERROR: error while accessing EJB resource, exception: "
+ e.getMessage());
e.printStackTrace();
}
return null;
}
}
);
} catch (javax.security.auth.login.LoginException e) {
System.err.println("ERROR: login failed with exception: " + e.getMessage());
e.printStackTrace();
// login failed, might want to provide relogin logic
}
You can use the com.ibm.websphere.security.auth.callback.WSCallbackHandlerImpl callback handler with a pure Java client, a client application container, enterprise bean, JavaServer Pages (JSP) files, servlet, or other Java 2 Platform, Enterprise Edition (J2EE) resources. See Example: Programmatic logins for more information about object request broker (ORB) security initialization requirements in a Java pure client.
User interface prompt programmatic login
javax.security.auth.login.LoginContext lc = null;
try {
lc = new javax.security.auth.login.LoginContext("WSLogin",
new com.ibm.websphere.security.auth.callback.WSGUICallbackHandlerImpl());
// create a LoginContext and specify a CallbackHandler implementation
// CallbackHandler implementation determine how authentication data is collected
// in this case, the authentication date is collected by GUI login prompt
// and pass to the authentication mechanism implemented by the LoginModule.
} catch (javax.security.auth.login.LoginException e) {
System.err.println("ERROR: failed to instantiate a LoginContext and the exception: "
+ e.getMessage());
e.printStackTrace();
// may be javax.security.auth.AuthPermission "createLoginContext" is not granted
// to the application, or the JAAS login configuration is not defined.
}
if (lc != null)
try {
lc.login(); // perform login
javax.security.auth.Subject s = lc.getSubject();
// get the authenticated subject
// Invoke a J2EE resources using the authenticated subject
com.ibm.websphere.security.auth.WSSubject.doAs(s,
new java.security.PrivilegedAction() {
public Object run() {
try {
bankAccount.deposit(100.00); // where bankAccount is a protected enterprise bean
} catch (Exception e) {
System.out.println("ERROR: error while accessing EJB resource, exception: "
+ e.getMessage());
e.printStackTrace();
}
return null;
}
}
);
} catch (javax.security.auth.login.LoginException e) {
System.err.println("ERROR: login failed with exception: " + e.getMessage());
e.printStackTrace();
// login failed, might want to provide relogin logic
}
Stdin prompt programmatic login
javax.security.auth.login.LoginContext lc = null;
try {
lc = new javax.security.auth.login.LoginContext("WSLogin",
new com.ibm.websphere.security.auth.callback.WSStdinCallbackHandlerImpl());
// create a LoginContext and specify a CallbackHandler implementation
// CallbackHandler implementation determine how authentication data is collected
// in this case, the authentication date is collected by stdin prompt
// and pass to the authentication mechanism implemented by the LoginModule.
} catch (javax.security.auth.login.LoginException e) {
System.err.println("ERROR: failed to instantiate a LoginContext and the exception:
" + e.getMessage());
e.printStackTrace();
// may be javax.security.auth.AuthPermission "createLoginContext" is not granted
// to the application, or the JAAS login configuration is not defined.
}
if (lc != null)
try {
lc.login(); // perform login
javax.security.auth.Subject s = lc.getSubject();
// get the authenticated subject
// Invoke a J2EE resource using the authenticated subject
com.ibm.websphere.security.auth.WSSubject.doAs(s,
new java.security.PrivilegedAction() {
public Object run() {
try {
bankAccount.deposit(100.00);
// where bankAccount is a protected enterprise bean
} catch (Exception e) {
System.out.println("ERROR: error while accessing EJB resource, exception: "
+ e.getMessage());
e.printStackTrace();
}
return null;
}
}
);
} catch (javax.security.auth.login.LoginException e) {
System.err.println("ERROR: login failed with exception: " + e.getMessage());
e.printStackTrace();
// login failed, might want to provide relogin logic
}
Do not use the com.ibm.websphere.security.auth.callback.WSStdinCallbackHandlerImpl callback handler for server side resources (like enterprise beans, servlets, JSP files, and so on). The input from the stdin prompt is not sent to the server environment. Most servers run in the background and do not have a console. However, if the server does have a console, the stdin prompt blocks the server for user input. This behavior is not desirable for a server process.
Related tasks
Developing programmatic logins with the Java Authentication and Authorization
Service
Related reference
Custom login module development for a system login configuration
Example: Customizing a server-side Java Authentication and Authorization
Service authentication and login configuration
Example: Getting the Caller Subject from the Thread
Example: Getting the RunAs Subject from the Thread
Example: Overriding the RunAs Subject on the Thread
Example: User revocation from a cache
Example: Programmatic logins