WAS v8.5 > Secure applications > Authenticate users > Use the JAAS programming model for web authentication > Develop custom login modules for a system login configuration for JAAS > Customize application login with JAAS > Step 1. Develop programmatic logins with JAAS.Develop programmatic logins with the JAAS
Use this topic to develop programmatic logins with the JAAS.
Java Authentication and Authorization Service (JAAS) represents the strategic application programming interfaces (API) for authentication.
JAAS replaces the Common Object Request Broker Architecture (CORBA) programmatic login APIs.
WebSphere Application Server provides some extension to JAAS:
- Refer to the information about developing applications that use CosNaming (CORBA Naming interface) for details on how to set up the environment for thin client applications to access remote resources on a server.
- If the application uses a custom JAAS login configuration, verify the JAAS login configuration is properly defined. See Configure programmatic logins for Java Authentication and Authorization Service for details.
- Some of the JAAS APIs are protected by Java 2 security permissions. If these APIs are used by application code, verify these permissions are added to the application was.policy file.
For details, see the following articles:
- Add the was.policy file to applications for Java 2 security
- Use PolicyTool to edit policy files for Java 2 security
- Configure the was.policy file for Java 2 security
For more details on which APIs are protected by Java 2 security permissions, check the IBM Developer Kit, Java Technology Edition; JAAS and WAS public APIs documentation in the Security: Resources for learning article.
Some of the APIs used in the sample code in this documentation and the Java 2 security permissions required by these APIs are in the following list:
- javax.security.auth.login.LoginContext constructors are protected by the javax.security.auth.AuthPermission "createLoginContext" object.
- javax.security.auth.Subject.doAs and com.ibm.websphere.security.auth.WSSubject.doAs methods are protected by the javax.security.auth.AuthPermission "doAs" object.
- javax.security.auth.Subject.doAsPrivileged and com.ibm.websphere.security.auth.WSSubject.doAsPrivileged methods are protected by the javax.security.auth.AuthPermission "doAsPrivileged" object.
- Enhanced model to Java EE resources for authorization checks.
Due to a design oversight in JAAS v1.0, the javax.security.auth.Subject.getSubject method does not return the Subject associated with the running thread inside a java.security.AccessController.doPrivileged code block. This oversight can present inconsistent behavior, which might have unwanted effects. The com.ibm.websphere.security.auth.WSSubject class provides a workaround to associate a Subject to a running thread. The com.ibm.websphere.security.auth.WSSubject class extends the JAAS model to Java EE resources for authorization checks. If the Subject associates with the running thread within the com.ibm.websphere.security.auth.WSSubject.doAs method or if the com.ibm.websphere.security.auth.WSSubject.doAsPrivileged code block contains product credentials, the Subject is used for Java EE resource authorization checks.
- User interface support for defining new JAAS login configuration.
We can configure a JAAS login configuration in the dmgr console and store the JAAS login configuration in a configuration repository. Applications can define a new JAAS login configuration in the dmgr console and the data is persisted in the configuration repository. However, WAS still supports the default JAAS login configuration format (plain text file) provided by the JAAS default implementation. If duplicate login configurations are defined in both the configuration repository and the plain text file format, the one in the repository takes precedence. Advantages to defining the login configuration in the configuration repository includes:
- Administrative console support in defining JAAS login configuration
- Central management of the JAAS login configuration
- Application support for programmatic authentication.
WAS provides JAAS login configurations for applications to perform programmatic authentication to the WebSphere security runtime. These configurations perform authentication to the WAS-configured authentication mechanism (Simple WebSphere Authentication Mechanism (SWAM), LTPA) and user registry (Local OS, LDAP, custom registries, or federated repositories) and Kerberos authentication based on the authentication data supplied. The authenticated Subject from these JAAS login configurations contains the required principal and credentials the WebSphere security runtime can use to perform authorization checks on Java EE role-based protected resources.
SWAM is deprecated in WAS v8.5 and will be removed in a future release.
Here are the JAAS login configurations provided by WAS:
- WSLogin JAAS login configuration. A generic JAAS login configuration can use Java clients, client container applications, servlets, JSP files, and EJB components to perform authentication based on a user ID and password, or a token to the security runtime for WAS. However, this configuration does not honor the CallbackHandler handler specified in the client container deployment descriptor.
- WSKRB5Login JAAS login configuration. A generic JAAS login configuration can use Java clients, client container applications, servlets, JSP files, and Enterprise JavaBeans™ (EJB) components to perform authentication based on a user ID and password, or a token to the security runtime for WAS. However, this configuration does not honor the CallbackHandler handler specified in the client container deployment descriptor.
- ClientContainer JAAS login configuration. This JAAS login configuration honors the CallbackHandler handler specified in the client container deployment descriptor. The login module of this login configuration uses the CallbackHandler handler in the client container deployment descriptor if one is specified, even if the application code specified one callback handler in the login context. This is for a client container application.
A Subject authenticated with the previously mentioned JAAS login configurations contains a com.ibm.websphere.security.auth.WSPrincipal principal and a com.ibm.websphere.security.cred.WSCredential credential. If the authenticated Subject is passed in the com.ibm.websphere.security.auth.WSSubject.doAs or the other doAs methods, the product security runtime can perform authorization checks on Java EE resources based on the com.ibm.websphere.security.cred.WSCredential Subject.
- Customer-defined JAAS login configurations.
We can define other JAAS login configurations to perform programmatic login which creates a custom Subject in either the client or server process. Certain credentials and principals are required in the Subject for the product security runtime to use it for sending authentication information from the client over a protocol or to use it for handling authorization on the server. The required credentials are generated from provided login modules.
The login module needed for a pure Java client login is as follows:
- com.ibm.ws.security.common.auth.module.WSLoginModuleImpl required;
In addition to using this login module, the callback handler used must be able to handle the following callback classes.
- javax.security.auth.callback.NameCallback
- javax.security.auth.callback.PasswordCallback
A username and password must be specified in the callback handler. Custom classes that are added to the Subject on the client side should get propagated to the server automatically whenever security attribute propagation is enabled. We can set the password to null to use identity assertion without a password.
For information about enabling propagation for a pure Java client, see the corresponding step in Propagating security attributes among application servers.
The classes added to the Subject must be Java serializable and de-serializable for this to occur properly.
The login modules needed for a server login are as follows:
- com.ibm.ws.security.server.lm.ltpaLoginModule required;
- com.ibm.ws.security.server.lm.wsMapDefaultInboundLoginModule required;
For information about the callbacks used for a server-side login configuration, see Customize a server-side Java Authentication and Authorization Service authentication and login configuration.
- Naming requirements for programmatic login on a pure Java client.
When programmatic login occurs on a pure Java client and the property com.ibm.CORBA.validateBasicAuth equals true, it is necessary for the security code to know where the SecurityServer resides. Typically, the default InitialContext is sufficient when a java.naming.provider.url property is set as a system property or when the property is set in the jndi.properties file. In other cases it is not desirable to have the same java.naming.provider.url properties set in a system-wide scope. In this case, there is a need to specify security specific bootstrap information in the sas.client.props file. The following steps present the order of precedence for determining how to find the SecurityServer in a pure Java client:
- Use the sas.client.props file and look for the following properties:
com.ibm.CORBA.securityServerHost=myhost.mydomain com.ibm.CORBA.securityServerPort=mybootstrap portIf we specify these properties, you are guaranteed that security looks here for the SecurityServer. The host and port specified can represent any valid WebSphere host and bootstrap port. The SecurityServer resides on all server processes and therefore it is not important which host or port you choose. If specified, the security infrastructure within the client process look up the SecurityServer based on the information in the sas.client.props file.- Place the following code in your client application to get a new InitialContext():
... import java.util.Hashtable; import javax.naming.Context; import javax.naming.InitialContext; ... // Perform an InitialContext and default lookup prior to logging // in so that target realm and 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(""); // programmatic login code goes here.Complete this step prior to running any programmatic login. It is in this code specified a URL provider for the naming context, but it must point to a valid WAS within the cell to which we are authenticating. Pointing to one cell allows thread specific programmatic logins going to different cells to have a single system-wide SecurityServer location.
- Use the new default InitialContext() method relying on the naming precedence rules described in the example of getting the default initial context.
Example: Programmatic logins using BasicAuth
This example illustrates how application programs can perform a programmatic login using BasicAuth.
Add Programmatic logins with Kerberos token:
LoginContext lc = null; try { lc = new LoginContext("WSKRB5Login", new WSCallbackHandlerImpl("userName", "password")); } catch (LoginException le) { System.out.println("Cannot create LoginContext. " + le.getMessage()); // Insert the error processing code } catch(SecurityException se) { System.out.println("Cannot create LoginContext." + se.getMessage()); // Insert the error processing code } try { lc.login(); } catch(LoginException le) { System.out.println("Fails to create Subject. " + le.getMessage()); // Insert the error processing codeAs shown in the example, the new login context is initialized with the WSKRB5Login login configuration and the WSCallbackHandlerImpl callback handler. Use the WSCallbackHandlerImpl instance on a server-side application where we do not want to be prompted. A WSCallbackHandlerImpl instance is initialized by the specified user ID, password, and realm information. The present Krb5LoginModuleWrapperClient class implementation specified by the WSKRB5Login login configuration can only retrieve authentication information from the specified callback handler. We can construct a login context with a Subject object, but the Subject is disregarded by the present Krb5LoginModuleWrapperClient implementation.
For a pure Java application client, the product provides two other callback handler implementations: WSStdinCallbackHandlerImpl and WSGUICallbackHandlerImpl, which prompt for user ID, password, and realm information on the command line and pop-up panel, respectively. Choose either of these product callback handler implementations, depending on the particular application environment. We can develop a new callback handler if neither of these implementations fit your particular application requirement.
There are additional callbacks that can be used with WSKRB5Login, WSAuthMechOidCallbackImpl and WSCcacheCallBackHandlerImpl. WSAuthMechOidCallbackImpl enabls you to specify the authentication mechanism OID, the Kerberos authentication mechanism OID value is "1.2.840.113554.1.2.2". The WSCcacheCallBackHandlerImpl enables you to specify the user name, Kerberos realm name, the Kerberos credential cache full path and whether to use the default location of the Kerberos credential cache. If you choose to use the default location of the Kerberos credential cache, then the Kerberos credential cache is ignored. If we are using Kerberos for authentication, then we have to update the sas.client.props file.
You also can develop our own login module if the default WSLoginModuleImpl implementation fails to meet all your requirements. WAS v8.5 provides utility functions the custom login module can use, which are described in the next section.
In cases where no java.naming.provider.url property is set as a system property or in the jndi.properties file, a default InitialContext context does not function if the product server is not at the localhost:2809 location. In this situation, construct a new InitialContext context programmatically ahead of the JAAS login. JAAS needs to know where the security server resides to verify the entered user ID or password is correct, prior to performing a commit method. By constructing a new InitialContext context in the way specified below, the security code has the information needed to find the security server location and the target realm.
The first line starting with env.put was split into two lines for illustration purposes only.
import java.util.Hashtable; import javax.naming.Context; import javax.naming.InitialContext; ... // Perform an InitialContext and default lookup prior to logging in so that target realm // and 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", "realm", "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 }
Related concepts:
Programmatic login for JAAS
Related
Customize application login with JAAS
Configure programmatic logins for Java Authentication and Authorization Service
Develop applications that use CosNaming (CORBA Naming interface)
Reference:
Example: Getting an initial context by setting the provider URL property
Security: Resources for learning