IBM WebSphere Application Server uses login modules extensively to perform various login tasks for the application server. JAAS is a J2SE API that provides services for authentication and authorisation. Since this is a very important and potentially complex part of WebSphere Application Server security, this article looks at the authentication service and how it is used in a variety of common login scenarios.
Although login and authentication are often used interchangeably, it is important to understand that there is a difference, since confusing the two during security design could lead to serious problems during implementation:
- Authentication is the validation of security credentials. The result of the authentication process is simply valid or invalid.
- Login is a process to collect the necessary credentials for an identity. The login process often involves authentication of the credentials.
- Authentication is a one time, stateless activity. Login has a longer term effect and carries some type of context, like a stateful activity.
The term realm in WebSphere Application Server defines a security boundary where identities are recognised. WebSphere Application Server simply uses a name generated from the user registry for the realm name; therefore the user registry and realm terms are often used interchangeably in the WebSphere world.
An out-of-box system like WebSphere Application Server has a solid functioning security. Imagine it as a boundary -- a balloon -- around the application server(s). When you start customizing security, for example writing a custom login module using JAAS, there are two things that can happen to this boundary:
- If the design and implementation are correct, the boundary just got extended: you got a bigger balloon.
- If the implementation is just a bit insecure, a hole is opened on the boundary: the balloon deflates or, worst case, explodes.
At this point the only recommendation is: think twice before deciding to customize login for applications or application servers; first and always try to use the built-in and supported product functionality.
Prerequisites
This article assumes basic understanding of the following topics:
- JAAS login modules, callback handlers, subject, principal
- WebSphere Application Server security
- Initial and propagation login
- Horizontal and downstream propagation.
See to the Resources for suggested reading materials.
This article applies to WebSpere Application Server V6.0.2 and later (including V6.1) on the distributed platform, and RMI/IIOP and CSIv2 used between application servers. This article does not apply to communication between application client and application server, although some scenarios may work in that environment. (Configuration details and the sample code in this article were tested with WebSphere Application Server V6.0.2.)
System login, application login
Here is a very simple explanation of what login means in WebSphere Application Server to give you an idea: The subject [Java™] holds the information about the identity executing the code in the application server. The purpose of the login module is to create, update or alter the current subject. Login modules are atomic parts of the login process; they are listed and reused in login configurations.
WebSphere Application Server distinguishes between two types of logins (login configurations to be exact):
- System logins are predefined in the application server and are used for internal login processes (for example: RMI/IIOP inbound, outbound). These configurations can be altered, mainly by adding new login modules, but they should not ever be removed. Be careful when altering the logins here, because the changes may break previously installed and working applications.
- Application logins can be used in J2EE applications.
Custom login modules and login configurations can be either part of system login or application login. The major difference is the scope of their availability. System logins require configuration for the application server, while application logins are configured for applications.
Two fundamental high-level login scenarios represent the basis for the various login implementations:
Login to a standalone application
The standalone application login is the simplest to picture (Figure 1).
Figure 1. Login to standalone application
- The user starts the application.
- Since it is a secured application that requires login, the application invokes the Login module.
- The Login module uses the Callback handler to...
- collect the login information from the user using various callbacks.
- The user enters the login information; for example: user name and password in a dialog box.
- The Login module receives the login information and makes a decision as to whether or not the user has access to the application. For example, the Login module can compare the user name and password against a local properties file.
The standalone login is not the most common scenario, although it is applicable to various cases in the distributed environment, like a server-side login.
Login in a client-server scenario
The client-server login is often used in the distributed environment. Figure 2 and the accompanying walkthrough shows a simple login process between two application servers.
Figure 2. Login in a client-server scenario
- An application makes a remote call on the sending server and invokes the outbound request component.
- The outbound request component uses the Login module to perform a login to make the remote invocation with the appropriate identity.
- The Login module uses the Callback handler to...
- collect the login information from the current security context. The security context may hold tokens to store the user identity. (In this case, the application server should already have a security context from previous logins.)
- The Login module returns the subject to the Outbound request so the request can use it for making the remote invocation.
- The Outbound request makes the remote invocation to the target server. The application server takes the available information from the subject, serializes it, and places it into the request as it is supported in the protocol (in this case, CSIv2).
- The Inbound request component receives the remote invocation on the target server side.
- The Inbound request uses the Login module to create a subject to handle the request.
- The Login module uses the Callback handler to collect the login information, which is...
- collected from the protocol used for making the remote invocation (in this case, CSIv2) over the network.
- The Login module returns the subject.
- The security context is created. This context stores the subject and other security information for the executing thread.
- The target server continues the execution after the request is processed.
Additional details for the distributed environment
In a distributed environment, the client is decoupled from the server, as far as the login process is concerned. There is no login process specific communication between client and server. In other words, the client is not contacting the server with login-specific content before making the actual remote call (business). The login information is transmitted together with the remote call(s).
Imagine the situation where a person is traveling from Europe to America. You could look at this as a sort of distributed system, where:
- The clients are the European airports.
- The servers are the American airports.
- The message is the traveler, moving from one specific airport to another specific airport.
- The immigration office acts like a login module.
- The passport is the subject and the stamp in the passport at the border is a type of token.
- The passport check at immigration is the equivalent of the login (handing over the passport) and authentication (checking the identity in a database at the location).
The point is that the traveler prepares the documents (passport) before the travel and carries them on the trip. There is no way to send the passport ahead and be sure that the person will be able to cross immigration at the destination. The traveler must cross the border at the destination in person, together with the passport.
This situation is exactly the same with WebSphere Application Server logins. The login information (credentials), later used for authentication or validation, travels together with the effective remote call, not as a separate package preceding the call.
Login scenario details
The previous description did not mention the login information that is stored on the individual application servers, or flown between the servers. The login information depends on several variables:
- What kind of login information is available?
- Is there trust between the servers?
- Do the servers belong to the same security realm?
- Do the servers share the same user registry?
- What does the protocol -- used for transmitting the login information -- support?
- What does the API -- used for login -- support (for example, tokens, authentication mechanisms, validation)?
The remainder of this article provides details for various login scenarios, each of which depends on the answers to these questions.
Detailed login scenarios and implementations
Based on specific security requirements and other variables, an application programmer may have to implement a specific login module, or more. The following sections describe various scenarios (or patterns) available for WebSphere Application Server. In addition, a spreadsheet showing a Login scenarios and requirements matrix is provided in the Download section to help you find the appropriate implementation based on your requirements.
The scenarios are:
- Identity propagation (default)
- Identity assertion
- Identity assertion with trust validation
- Server-side identity assertion
- Outbound identity mapping from application code
- Outbound identity mapping using a custom login module
- Inbound identity mapping
- Security attribute propagation
- Custom token propagation
- Custom token object propagation with login
Scenario 1: Identity propagation (default)
The sending server only sends the user identity (X.509 certificate, principal name, or distinguished name (DN) based on the credentials used for the initial login) to the target server. The sending server does not propagate the password or any other private credentials (secret). For example, when a servlet on the sending server makes a remote call (RMI/IIOP) to the target server, the client's identity (the one that accessed the servlet) is sent over with the communication.
Why use this scenario?
- This scenario is simple and it does not require any customization or specific configuration.
Conditions
- The servers must share the user registry.
- The servers must share the same LTPA keys.
- Having the two servers in the same cell is not a requirement, but the two previous conditions suggest that they are. They could be two standalone servers with the same LTPA keys and share the same user registry.
How does it work?
- The sending server has the security context already with the client's identity. When sending the request, the outbound login picks up the credentials for the identity and sends the serialized data over to the target server. The credentials are stored and sent in the form of an LTPA token. The trust is setup between the two servers by sharing the LTPA keys, and so there is no need for transmitting the server's identity.
- The target server receives the request and passes the deserialized token to the application server for decryption.
- The target server invokes the login modules from the RMI_INBOUND login configuration to pick up the credentials from the incoming request. Login modules are used to retrieve and decrypt the various tokens to get to the user credentials.
- The credentials are used to create a subject to execute the code on the target server.
In the meantime, a CSIv2 session is established and used for future requests. The security subject is associated with the CSIv2 session. As long as the session is open and valid there is no reason to run the login process again.
Configuration
There is no need for any specific configuration; WebSphere Application Server uses identity propagation for RMI/IIOP using CSIv2 communication as a default.
Customization
There is no customization required for the default scenario.
Scenario 2: Identity assertion
This is an enhanced version of identity propagation (default Scenario 1).
In the identity assertion scenario, the servers are not using LTPA keys to establish trust. To avoid the risks related to trusting the sending server, server validation is introduced into the assertion process. During server validation, the target server examines whether the sending server is trustworthy or not. It does the check by simply comparing the sending server's identity, after authentication, to a pre-configured list of trusted server's identities. The identity asserted on the sending side takes the form of the original credentials provided for the initial login (for example, user ID, DN, certificate).
Why use this scenario?
- This scenario does not require sharing LTPA between the servers, and therefore, the servers do not have to be in the same cell.
Conditions
- The sending server and the target server must share the same user registry.
- The Identity Assertion feature must be enabled and configured on both application servers (sending and target).
- The target server has to list the sending server on the trusted servers list.
Risks
- The asserted identity is not transmitted as a token; it is plain text without encryption. To address this issue, you should use an SSL connection between the sending and the target server.
How does it work?
- The sending server has the security context already with the client's identity. The server sends the serialized credentials, including the sending server's identity for basic authentication, to the target server. The server ID and password are sent in a GSS token, and are produced and consumed using the JGSS API. This part of the login process does not use the JAAS API. The client's identity is sent as the user name (with no password), because basic authentication is used.
- The target server receives the request, retrieves the GSS token, extracts the server identity, authenticates it, and compares it to the list of trusted servers' identities. If the sending server is trusted, the execution continues.
- The target server invokes the login modules from the RMI_INBOUND login configuration to pick up the credentials from the incoming request.
- The login modules use the NameCallback callback to retrieve the client's identity, and build a subject that is used to execute the code in the application server.
- The application server uses the client identity from the assertion to run the code on the target server.
Configuration
Make sure the servers do not share the same LTPA keys; generate two different LTPA keys for the two servers:
Configure identity assertion for the sending server:
- Enable identity assertion in WebSphere Application Server by navigating to Security => Global security => Authentication protocol => CSIv2 outbound authentication.
- Restart the server.
Configure identity assertion for the target server:
- Enable Identity assertion by navigating to Security => Global security => Authentication protocol => CSIv2 inbound authentication.
- In this example, add the sending server's server ID to the Trusted servers field: uid=wasserver1,dc=demo,dc=ibm,dc=net (it does not have to be fully qualified, depending on the user registry configuration). If there is more than one server, use the | (pipe) symbol to list them.
- Restart the servers.
Customization
There is no customization required. This scenario is simply based on configuration settings.
Scenario 3: Identity assertion with trust validation
This scenario enhances the identity assertion scenario (Scenario 2) with the option to programmatically validate the asserted user identity. The trust validation is required on the sending server side to validate the asserted identity. This might be necessary because, technically, it is possible to insert any user identity, even a false identity, using the given programming model.
Why use this scenario?
- This scenario does not require sharing LTPA between the servers, and therefore the servers do not need to be in the same cell.
- It provides the flexibility to assert any valid user identity programmatically.
- Customization is done only on the sending server-side. No coding is required for the target server.
Conditions
- The identity assertion feature has to be enabled and configured on both application servers (sending and target).
- The sending server and the target server must share the same user registry.
- The target server must list the sending server on the trusted servers list.
Risks
- Any trust validation is left to be implemented by the developers. Implementation must be done properly to avoid any security issues.
- The asserted identity is not transmitted as a token; it is plain text without encryption. To address this issue, you should use an SSL connection between the sending and the target server.
How does it work?
- The sending server already has an existing security context with a specific identity.
- Before the sending server makes the remote invocation, the client code performs a login using a custom application login configuration:
- The first login module, implemented by the developer, picks up the new identity. For example, callbacks can be used to provide the details for the new identity.
- After validating the identity (validating trust), the identity information is placed into the login's shared state.
- The second login module, shipped with the application server, picks up the identity information from the shared state and performs the actual identity switch in the application server.
- When the application code on the sending server makes the remote call, the identity will reflect the new, asserted identity. When the identity assertion attribute is enabled for the CSIv2 outbound configuration, the subject is switched before making the remote call.
- The server sends the serialized credentials (together with the asserted identity), including the sending server's identity (server ID and server password), over to the target server. The server ID and password are sent in a GSS token, which is produced and consumed using the JGSS API. This part of the login process does not use the JAAS API. The client's identity is sent as the user name from the basic authentication.
- The target server receives the request, retrieves the GSS token, extracts the server identity and compares it to the list of trusted server identities. If the sending server is trusted, the execution continues.
- The target server invokes the login modules from the RMI_INBOUND login configuration to pick up the credentials from the incoming request.
- The login modules use the NameCallback callback to retrieve the client's identity, and build a subject that is used to execute the code in the application server.
- The application server automatically switches over to the identity used in the assertion. From here, the client's identity is used to run the code on the target server.
Configuration
Make sure that the servers do not share the same LTPA keys; generate two different LTPA keys for the two servers.
- Enable identity assertion for the sending server by navigating to Security => Global security => Authentication protocol => CSIv2 outbound authentication.
- On the sending server, configure a new application login to handle the identity assertion:
- Create a new Application Login configuration.
- Add the custom login module, and make sure you add this first. Using the sample code provided with this article, the configuration is the following:
- Login configuration name:
CustomIDassertion - Module class name:
com.ibm.issw.security.loginmodules.RMI_IDAssertion_LM - Use login module proxy: Enabled
- Authentication strategy: Required
- Login configuration name:
- Add the WebSphere Application Server identity assertion login module as the second module:
- Module class name:
com.ibm.wsspi.security.common.auth.module.IdentityAssertionLoginModule - Use login module proxy: Enabled
- Authentication strategy: Required
- Module class name:
- Restart the sending server.
- Configure identity assertion for the target server:
- Enable Identity assertion by navigating to Security => Global security => Authentication protocol => CSIv2 inbound authentication.
- Add the sending server's server ID to the Trusted servers field; in our example: cn=wasserver1,dc=demo,dc=ibm,dc=net. If you have more than one server use the | (pipe) symbol to list them.
- Restart the target servers.
Customization
The custom part here is to implement a new custom login module to collect the credentials for the asserted identity and to perform the validation for the identity. For more information about the custom login module, refer to the source code RMI_IDAssertion_LM.java and embedded comments from the download file included included with this article.
Sample code
The sample login module uses one of WebSphere Application Server's callback handlers to collect the asserted identity. An alternative to this is to develop and use a custom callback handler in the application login module responsible for collecting the information. The actual identity used for assertion is defined in the Web application as an environment variable: WEB_USER2, with the value of user2. You can change this value by simply editing the web.xml file. In actual applications, there would be a more complex logic to collect the user identity for assertion.
Scenario 4: Server-side identity assertion
The server-side identity assertion process works the same way as the identity assertion with trust validation (Scenario 3). The difference is that there is no passing of security information in any protocol (no CSIv2) between the participating components. Since the change happens locally (in-process) the application server itself has to change the security context for the execution.
This scenario is an implementation of the login to a standalone application scenario. From the programming model point of view, this scenario is the same as Scenario 3 (Identity assertion with trust validation). The reason for describing it as a separate scenario is because it is different from an application design point of view.
Server-side identity assertion is useful when the application has to change the identity when only server-side components are involved, or when the infrastructure does not provide a security interceptor (or handler) to perform the login. For example, a message-driven bean can setup a proper identity, using the information from the message, before invoking a session EJB. Another example: the user identity is passed as a parameter defined in the method signature.
Why use this scenario?
- If there is a need to switch identity on the server-side and it cannot be done any way other than programmatically.
- When a specific protocol (for example, CSIv2) is not available to propagate security information for identity assertion, but the identity is available as part of the message.
Conditions
- This scenario assumes that the identity used for assertion on the server-side is already available. It can be a part of a remote call from the sending server, or simply a result of the application logic on the target server.
Risks
- The identity validation is performed by custom code.
- The server-side identity assertion behavior is not declarative; there is an overlap between the developer, assembler, and deployer roles that could cause confusion during debugging or tracing. (Proper documentation of the code and debug/trace information in the code can resolve this problem.)
How does it work?
- The application acquires the identity for assertion.
- The application code invokes a customer application login configuration for the server-side identity assertion.
- The application starts to execute the login modules from the configuration. The first login module should be a custom login module:
- The custom login module picks up the new identity (this depends on the requirements and the implementation).
- The identity should be checked against the user registry to ensure the validity of the new identity.
- The identity is placed in the login shared state under specific keys.
- The last login module, IdentityAssertionLoginModule, picks up the identity information from the shared state and builds a new subject.
- The application code receives the new subject, then invokes the WSSubject.setRunAsSubject(returned_subject) method to switch identity for the current thread.
- After the previous action, the code is running under a new identity.
Configuration
On the target server, configure a new application login to handle the identity assertion:
- Create a new application login configuration, named
Server_side_identity_assertion. - Add the custom login module. Make sure this is the first login module on the list. Using the sample code, specify the following:
- Login configuration name:
CustomServerIDassertion - Module class name:
com.ibm.issw.security.loginmodules.RMI_IDAssertion_LM - Use login module proxy: Enabled
- Authentication strategy: Required
- Login configuration name:
- As the second module, add the WebSphere Application Server identity assertion login module:
com.ibm.wsspi.security.common.auth.module.IdentityAssertionLoginModule. - Restart the server.
Since it does not use CSIv2, server-side identity assertion does not require any identity assertion configuration for CSIv2 communication.
Customization
The same customization applies as in Scenario 3.
Sample code
In this particular sample, the asserted identity for the server side is simply sent as a method parameter of the remote invocation. The actual identity used for assertion is defined in the sending server's Web application as an environment variable, WEB_USER2, with the value of user2. Edit the web.xml file to change this value, if required.
Although this scenario does not require sharing the user registry or the LTPA keys, the sample was developed using identity propagation (default propagation) for the remote call to make the configuration easier.
Scenario 5: Outbound identity mapping from application code
Identity mapping is about changing one identity to a different identity from a different user registry. While identity assertion (see previous scenarios) can change identity, it can only make the change within the same user registry. There are several ways to map the identity, such as looking it up from a database, using an algorithm, and so on; these techniques are beyond the scope of this document.
Mapping an identity can serve different purposes:
- It can implement a scenario, such as the run-as mapping for EJB components.
- It can implement a mapping between two user registries using some mapping mechanism.
There are two outbound mapping scenarios. In the first scenario (the second is Scenario 6), identity mapping is performed from the application code, without using and configuring custom login modules. In this case, the application developer is responsible for retrieving the current identity, mapping and creating the new identity, and performing a remote login to the target server, before making the remote invocation.
Why use this scenario?
- When it is necessary to change an identity between different user registries.
- The sending and target servers do not trust each other.
- When LTPA tokens cannot be used to transmit the identity because the LTPA keys are not shared.
- Changing the application server configuration (adding custom login modules) is not available or not permitted.
- Handle identity mapping from the application code is the preferred method.
Conditions
- The application has to map the user identity to credentials. These credentials will be validated on the target server (for example, user ID and password).
Risks
- Sensitive data (such as password) is sent over the network. Use SSL between the sending and the target server to ensure secure communication.
- The scenario requires the user credentials (such as user ID and password) to be presented for initial login. You must find a secure way to store and retrieve this sensitive credential information.
How does it work?
- Before making the remote invocation, the application code has to create a new subject that is valid on the target server.
- You must retrieve the current identity and then use a mapping function to come up with a new identity.
- To create a new subject, the application has to login to the target server (target realm) using the WSLogin application login. The result of the login is the new subject.
- Using the new subject, the application makes the remote invocation.
Configuration
This scenario requires the use of two different user registries for each application server. Configure the sending server to use one user registry and the target server to use another one. Outbound mapping between servers works without sharing LTPA keys. For a more realistic test, make sure that the application servers use different LTPA keys.
Using outbound identity mapping requires changes in the existing configuration for the WSLogin application login on the sending server:
- Open Security => Global security => JAAS Configuration => Application logins and select WSLogin.
- Select the com.ibm.ws.security.common.auth.module.WSLoginModuleImpl item from the JAAS Login Modules.
- Alter these two Custom properties for this login module, changing the value for both to true:
- use_realm_callback
- use_appcontext_callback
- Restart the server.
Customization
Customization for this scenario is only required in the application code, and does not require development of a new login module. For more details, see the OutboundIdentityMappingOutbound.java source code in the download section.
Sample code
The identity mapping uses a properties file to determine the mapped user identity. The user_mapping.properties file is used in all three identity mapping scenarios. The section related to each scenario is marked with a comment.
Here is the format for the file to follow:
user1->10.10.10.62=user1@Target;10.10.10.62:389;byte2eat |
user1= original user ID10.10.10.62= target server's addressuser1@Target= mapped user ID10.10.10.62:389= realm for the remote serverbyte2eat= password for the mapped user
The location for the properties file is configured in the Web application (web.xml) in an environment variable. The default value is: /opt/IBM/WebSphere/AppServer/properties/user_mapping.properties. Make sure the directory structure points to the proper location before testing.
Scenario 6: Outbound identity mapping using a custom login module
The second outbound identity mapping scenario uses a custom login module on the sending server side. The advantage of this approach is that it does not require additional application code to perform the identity mapping. The identity mapping and the identity switch is performed by an outbound custom login module. The code in the custom login module is almost the same as the code from Scenario 5 used in the application.
Why use this scenario?
- When change of identity is required between different user registries (realms).
- The sending and target servers do not trust each other.
- When LTPA tokens cannot be used to transmit the identity because the LTPA keys are not shared.
- The preferred way to handle identity mapping is in the application server, performed by the infrastructure. In other words, applications should not include security-specific infrastructure code.
Conditions
- The user identity must be mapped to credentials by the login module. These credentials (such as user ID and password) will be validated on the target server.
Risks
- Sensitive data (like password) is sent over the network. Use SSL between the sending and the target server to ensure secure communication.
- This scenario requires user credentials to be presented for initial login (such as user ID and password). You must find a secure way to store and retrieve the sensitive credential information.
How does it work?
- The sending server makes a remote call to the target server.
- Prior to the actual call, the sending server invokes the login modules from the RMI_OUTBOUND login configuration. The custom login module is the first to invoke.
- The outbound login module creates a new subject that is valid on the target server.
- The login module must retrieve the current identity and then use a mapping function to come up with a new identity.
- To create a new subject, the login module must login as if it was logging in to the target server (using the target realm), using the WSLogin application login. The result of the login is a new subject.
- The new subject simply has to replace the old one. In the commit() method of the login module, a privileged code clears up the current subject and replaces the principals, and the public and private credentials.
- After finishing with the login module, the remote call is made under the new subject.
Configuration
- Configure the new login module on the sending server:
- Add the custom login module to the RMI_OUTBOUND login configuration. Make sure you add this first. Specify the following:
- Module class name:
com.ibm.issw.security.loginmodules.OutboundMapping_LM - Use login module proxy: Enabled
- Authentication strategy: Required
This sample requires additional, specific configurations described below.
- Module class name:
- After applying the changes, click the Set order button to move the login module to the top of the list.
- Add the custom login module to the RMI_OUTBOUND login configuration. Make sure you add this first. Specify the following:
- Modify the WSLogin application login configuration on the sending server:
- Open the Security => Global security => JAAS Configuration => Application logins and select WSLogin.
- Select the com.ibm.ws.security.common.auth.module.WSLoginModuleImpl item from the JAAS Login Modules.
- Alter the two Custom properties for this login module, changing the value for both to true:
- use_realm_callback
- use_appcontext_callback
- Enable the Custom outbound login feature for the CSIv2 outbound authentication on the sending server.
- Restart the server.
Customization
This scenario requires a new custom login module and configuration. The code sample for the login module can be found in OutboundMapping_LM.java in the download materials.
This scenario is also dependent on the properties file describing the mapping between current and new identities. A custom property holds the location for the property file, at Global security => System login configuration => RMI_OUTBOUND => JAAS login modules => com.ibm.issw.security.loginmodules.OutboundMapping_LM => Custom properties. Create a new property, named mapping.file, with the value of the location of the file (for example, /opt/IBM/WebSphere/AppServer/properties/user_mapping.properties). The format of the entries for this scenario is the following:
10.10.10.61|389/user1->10.10.10.62|389=user1@Target;byte2eat |
10.10.10.61|389/user1= original unique user ID with the realm10.10.10.62|389= target server's realmuser1@Target= mapped user IDbyte2eat= mapped user's password
The | (pipe) symbol is used here instead of the : (colon) for the configuration because of Java limitations in processing the properties file.
Scenario 7: Inbound identity mapping
Inbound mapping can help change the identity on the target server from information received from the sending server. In cases when outbound mapping does not meet the requirements for identity mapping, inbound identity mapping can open up new options. Inbound mapping heavily relies on the trust between the sending and the target servers.
Why use this scenario?
- The user identity does not exist in the target server's user registry. In other words, the sending server does not share user registry with the target server.
- The sending server does not have any knowledge of the mapping mechanism or the new user identity.
- When the secure credentials are not available to create a new identity.
- When the mapping on the sending server is not known or available.
Conditions
- The sending and target servers must trust each other.
- There has to be a mechanism to transmit the actual user identity, such as identity assertion.
- The target server must have the intelligence to map the incoming identity to the new identity. If this capability is not available on the target server side, you should consider an outbound identity mapping scenario instead.
How does it work?
- The sending server makes a remote invocation and places the identity for the invoker into the request.
- The target server receives the incoming request and starts invoking the login modules from the RMI_INBOUND login configuration.
- The first login module is the custom inbound mapping login module:
- The login module determines the identity for the invocation by performing the mapping.
- The new identity is checked against the user registry configured for the target server for validation purposes.
- The valid user's identity (with a few other attributes) is then stored in the shared state used in other login modules.
- A latter login module (com.ibm.ws.security.server.lm.wsMapDefaultInboundLoginModule) uses the information from the shared state to construct the new subject for further execution.
- By the end of the login process, the identity is switched to the new identity on the target server.
Configuration
- Configure the new login module on the target server:
- Add the custom login module to the RMI_INBOUND login configuration. Specify the following:
- Module class name:
com.ibm.issw.security.loginmodules.InboundMapping_LM - Use login module proxy: Enabled
- Authentication strategy: Required
This sample requires additional, specific configurations described below.
- Module class name:
- After applying the changes, use the Set order button to move the login module to the top of the list.
- Add the custom login module to the RMI_INBOUND login configuration. Specify the following:
- Restart the server.
Customization
This scenario requires a custom login module for the target server to perform the identity mapping. For more information read the source in the InboundMapping_LM file.
This scenario is also dependent on the properties file describing the mapping between current and new identities. The location of the file is configured as a custom property at Global security => System login configuration => RMI_INBOUND => JAAS login modules => com.ibm.issw.security.loginmodules.InboundMapping_LM => Custom properties. Create a new property, named mapping.file, with the value specifying the location of the file (for example: /opt/IBM/WebSphere/AppServer/properties/user_mapping.properties). The format of the entries for this scenario is:
10.10.10.61|389/uid-user1,ou-People,dc-demo,dc-ibm, dc-net=uid=user1@Target,ou=People,dc=demo,dc=ibm,dc=net |
10.10.10.61|389/uid-user1,ou-People,dc-demo,dc-ibm,dc-net= original fully qualified user ID with the realmuid=user1@Target,ou=People,dc=demo,dc=ibm,dc=net= mapped fully qualified user ID
The | (pipe) symbol is used here instead of the : (colon) for the configuration because of the limitations of the properties file processing in Java. Also, the = (equal) sign is replaced by the - (hyphen) in the original user ID for the same reason.
Before continuing further in this article, you must be comfortably familiar with the various types of security tokens in WebSphere Application Server, such as propagation, authentication, authorization, single sign-on tokens.
Scenario 8: Security attribute propagation
Security attribute propagation is a service provided by the application server to propagate various attributes, tokens, or objects related to the security context. The sending server can insert attributes into the security context that is sent to the target server. Security attributes are transmitted using a specific protocol; in the case of RMI/IIOP, the protocol is CSIv2, which has a dedicated layer for transmitting security attribute information during a remote invocation.
In truth, security attribute propagation is a bit more complicated than the above definition, because the attributes can be WebSphere tokens, custom tokens, attributes on a token, or custom objects. Propagation can also happen in different directions: horizontal or downstream. (See the WebSphere Application Server Information Center for more information.)
The attribute is a key-value pair of strings with this structure:
token-attributes {
String key
String[] values
} |
There is a security helper class in WebSphere Application Server for inserting attributes into and reading attributes from the security context. WebSphere Application Server employs a special propagation token to carry the attributes.
Why use this scenario?
- When additional security related information should be present, attached to the actual user identity (subject), then security attributes can hold this information.
- It is very simple to use and requires minimal coding to propagate custom security information between servers. It does not require custom login modules or new login module configurations.
- There is no need to share token classes between application servers.
Conditions
- Security attribute propagation feature must be enabled on the application servers.
- Setting and getting attributes happens in the application code.
- Attributes are stored as String with a String type key, which may require serialization and deserialization of objects.
- If the servers are not in the same realm, the trusted target realm list must be configured.
How does it work?
The default propagation token that is used for propagating the security attributes is attached to the running thread. Security attribute propagation takes care of attaching the attribute to a specific token and the serialization/deserialization and propagation of the token. You can simply use put/get methods to have access to the security attributes.
- The sending server's application programmatically puts an attribute into the propagation token.
- When the security attribute propagation service is enabled, the application server automatically picks up the propagation token from the thread and inserts it into the remote invocation using the CSIv2 protocol.
- The target server receives the request and retrieves the propagation token. The token is attached to the thread.
- The application on the target server can query the propagation token and retrieve any necessary attribute.
Configuration
To keep the sample simple, have both servers using the same user registry and that they share LTPA keys:
- Enable Security attribute propagation for the sending server by navigating to Security => Global security => Authentication protocol => CSIv2 outbound authentication.
- Restart the sending server.
- Enable Security attribute propagation for the target server by navigating to Security => Global security => Authentication protocol => CSIv2 inbound authentication.
- Restart the target server.
Configuration options:
Security attribute propagation also works in environments where servers are not sharing the same user registry and the LTPA keys. In these cases, the Trusted target realms field must be configured for the sending server at CSIv2 outbound authentication. To test this option:
- Follow the configuration steps for the servers from the Outbound identity mapping using custom login module scenario (Scenario 6).
- Configure security attribute propagation as described above.
- Add the target server's realm to the CSIv2 outbound authentication on the sending server; for example, 10.10.10.62:389.
To meet specific requirements, scenarios and configurations can be mixed like this, more on this later.
Customization
Customization for this scenario is quite minimal. You need to add a few lines of code to the sender and the target application to place and receive security attributes. See the applicable source code for more details: for sending, see SecurityAttributePropagationOutbound.java, for receiving, see SecurityAttributePropagationInboundBean.java.
Sample code
The sample code employs a custom authentication token. There are various other types, but from the programming model, implementation, and configuration viewpoints, they are essentially the same. The attributes on the token are simply hardcoded in the custom login module code. These attributes would typically be set based on some logic, or they could be collected using various callbacks during the login process.
Scenario 9: Custom token propagation
Propagating custom tokens gives an additional level of flexibility to security attribute propagation (Scenario 8), in that it enables the developer to name, specify the type, and implement any token. This token must implement a specific interface to let WebSphere Application Server handle the serialization/deserialization, propagation of the token.
WebSphere Application Server provides interfaces for a number of specific token types. Each type of token has a different purpose and WebSphere Application Server treats each one appropriately. Such differences include what the token is attached to (thread, subject), in which direction it is propagated (downstream, horizontal), and what it is used for (authentication).
Why use this scenario?
- Tokens can carry additional information related to security. In some cases, a simple user identity is not enough to build a proper security context. In other cases, the original user credentials cannot be propagated the way tokens can be.
- When downstream propagation does not meet the requirements; for example, when horizontal propagation is required.
- When the currently available tokens are not suitable; for example; in case of integrating with another application server.
Conditions
- The token implementation classes have to be shared between the application servers.
- WebSphere Application Server has a set of predefined token types (interfaces) with specific behaviors. Any custom implementation must consider these behaviors.
Risks
- The custom token implementation should worry about the sensitive data stored in the token, and therefore it should perform some type of encryption in the serializing and deserializing process.
Variations for using tokens
When working with tokens, the whole lifecycle and lifetime of the tokens should be considered. It is important to understand the various types of tokens in WebSphere Application Server, how they get propagated, and where they apply. The WebSphere Application Server Information Center has an excellent overview of the different types of tokens, but let's take a quick look at the bigger picture of how they are used.
First of all, the lifetime of tokens are not restricted to a single remote invocation, or to a single protocol. Their lifetime spans multiple calls and probably multiple protocols as well. The lifetime is most likely bounded by an expiration time, especially in a distributed environment where invalidating a token can be quite a challenge.
The life-cycle of a token is simple: the token is created early during the first user interactions with the applications as part of the initial login. The token then either expires or gets invalidated (if possible). In most cases, a token survives the entire user session; otherwise, it has to be reissued, and reissuing a token may require a new initial login. When the token is available, WebSphere Application Server then performs a propagation login using the available tokens.
Different variations are available in terms of handling tokens in the login modules. The security architect can decide the type of behavior required for the application, and the application developer can use the appropriate variation from the WebSphere SPI. Figure 3 shows the variations.
Figure 3. Token handling variations
Figure 3 shows three variations (A,B,C) of a client application making a call to the sending server. In each variation:
- The shaded circles represent the application code.
- The sending server might use a specific inbound and an outbound login module to handle tokens.
- The sending server makes a remote call to the target server.
- The target server might use a specific inbound and an outbound login module to handle tokens.
- The target server might make a remote call to downstream servers.
- A non-shaded login modules actively handles tokens, a shaded login module (if there is one) does not.
Variation A:
Why do we only need the inbound custom login module? Or the question may sound like: Where is the token coming from if we only have a custom inbound login module, and why is there no custom outbound login module as well? Remember, when talking about tokens, you have to consider the entire lifetime of the token and not be narrowed down to a single invocation. The very first time the user (or an external system) accesses the application, the first login module is an inbound login module. This inbound login module generates the token. Once the token is generated, it is maintained and propagated for all subsequent calls, either horizontal or downstream. It also means that the token is always available in the subject (or the execution thread). Since the token is available, it is automatically propagated, and so there is no need for a specific outbound login module to create the token.
This is the default variation for all WebSphere Application Server tokens. The sample provided with this article follows this variation.
Variation B:
Tokens can also be used for transmitting security related information for a single remote call. In this case, the sending server prepares the token for the remote call in an outbound login module. The target server picks up the token using an inbound login module.
Variation C:
This variation is the most complete with all the login modules actively handling tokens. It is basically an extended Variation A scenario, where the outbound login modules can also access the tokens, for any reason.
How does it work?
- The sending server makes a remote invocation.
- The application server automatically picks up the tokens from the subject and the execution thread, and inserts them into the remote invocation using the CSIv2 protocol. The custom token behaves like any other WebSphere security token, and the application server automatically transmits it. During the transmission, the tokens are serialized and, preferably, encrypted as well.
- The target server receives the request with the tokens embedded in the protocol (CSIv2).
- The target server deserializes the tokens and attaches them to the subject or the thread, depending on the type of the token. For more information about how tokens are treated refer to the WebSphere Application Server Information Center.
Configuration
The sample code and the configuration described below is an implementation of Variation A. The configurations for the other variations are very similar, the difference being where the login module is configured on the servers: RMI_INBOUND or RMI_OUTBOUND.
- Configure the new login module on the sending server:
- Add the custom login module to the RMI_INBOUND system login configuration. Make sure it is placed after the com.ibm.ws.security.server.lm.wsMapDefaultInboundLoginModule login module. Specify these values:
- Module class name:
com.ibm.issw.security.loginmodules.CustomAuthenticationToken_LM - Use login module proxy: Enabled
- Authentication strategy: Required
- Module class name:
- Repeat step 1a for the DEFAULT, WEB_INBOUND system login configuration.
- Add the custom login module to the RMI_INBOUND system login configuration. Make sure it is placed after the com.ibm.ws.security.server.lm.wsMapDefaultInboundLoginModule login module. Specify these values:
- Configure the new login module on the target server.
- Add the custom login module to the RMI_INBOUND system login configuration. Make sure you add this after the com.ibm.ws.security.server.lm.wsMapDefaultInboundLoginModule login module. Specify these values:
- Module class name:
com.ibm.issw.security.loginmodules.CustomAuthenticationToken_LM - Use login module proxy: Enabled
- Authentication strategy: Required
- Module class name:
- Repeat step 2a for the DEFAULT, WEB_INBOUND system login configurations.
- Add the custom login module to the RMI_INBOUND system login configuration. Make sure you add this after the com.ibm.ws.security.server.lm.wsMapDefaultInboundLoginModule login module. Specify these values:
Configuration options:
Custom token propagation also works in environments where servers are not sharing the same user registry and LTPA keys, just like in the case of security attribute propagation (Scenario 8). Custom token propagation does not require the configuration of Trusted target realms. To test this case, simply use the configuration from the Outbound identity mapping using custom login module scenario (Scenario 6) to setup an environment where neither the LTPA keys nor the user registry are shared between servers.
Customization
To propagate a custom token, get hold of the subject. One way to do this is to perform a standard (or custom) login on the sending server side and use a custom login module on the target server side. Decide:
- What type of token is going to be used?
- How should the token be propagated?
- What is the token used for?
(For more information about the different type of the tokens, see the WebSphere Application Server Information Center.)
The custom components needed for this scenario:
- Custom token implementation for a particular token type.
- Custom login module for inbound requests to create or retrieve the token, depending whether it is an initial login or a propagation login.
Scenario 10: Custom token object propagation with login
Custom token object, for the lack of a better name, is really just a regular serializable object. Using a custom token object for propagation is the most flexible scenario in propagation, since it is not bound by any custom token restrictions.
Why use this scenario?
- When String type key-value pairs are simply not sufficient to propagate the necessary security attributes.
Conditions
- The custom object implementation classes must be shared between the application servers.
Risks
- The custom object implementation should worry about the sensitive data stored in the object, and therefore should include encryption in the serializing and deserializing process.
How does it work?
- The sending server makes a remote invocation.
- The application server automatically picks up the object from the subject, as one of the private credentials, and inserts it into the remote invocation using the protocol (CSIv2). The custom token object behaves like other WebSphere security tokens, and the application server automatically transmits it. During the transmission, the tokens are serialized and, preferably, encrypted as well.
- The target server receives the request with the object embedded in the protocol (CSIv2).
- The target server deserializes the object and attaches it to the subject.
Configuration
The sample code is an implementation of Variation A of Scenario 9, and the configuration described below is specific to this variation.
- Configure the new login module on the sending server:
- Add the custom login module to the RMI_INBOUND system login configuration. Add this after the com.ibm.ws.security.server.lm.wsMapDefaultInboundLoginModule login module. Specify these values:
- Module class name:
com.ibm.issw.security.loginmodules.CustomTokenObject_LM - Use login module proxy: Enabled
- Authentication strategy: Required
- Module class name:
- Repeat step 1a for the DEFAULT, WEB_INBOUND system login configurations.
- Add the custom login module to the RMI_INBOUND system login configuration. Add this after the com.ibm.ws.security.server.lm.wsMapDefaultInboundLoginModule login module. Specify these values:
- Configure the new login module on the target server:
- Add the custom login module to the RMI_INBOUND system login configuration. Add this after the com.ibm.ws.security.server.lm.wsMapDefaultInboundLoginModule login module. Specify these values:
- Module class name:
com.ibm.issw.security.loginmodules.CustomTokenObject_LM - Use login module proxy: Enabled
- Authentication strategy: Required
- Module class name:
- Repeat step 2a for the DEFAULT, WEB_INBOUND system login configurations.
- Add the custom login module to the RMI_INBOUND system login configuration. Add this after the com.ibm.ws.security.server.lm.wsMapDefaultInboundLoginModule login module. Specify these values:
Configuration options:
Custom token object propagation also works in environments where servers are not sharing the same user registry and LTPA keys, just like in the case of Security attribute propagation (Scenario 8). Custom token object propagation does not require the configuration of Trusted target realms. In this case, simply use the configuration from the Outbound identity mapping using custom login module scenario (Scenario 6) to setup an environment where neither the LTPA keys nor the user registry is shared between servers.
Customization
The customization is mostly the same as the customization in Scenario 9, except the implementation of a custom object is independent of the WebSphere tokens.
The scenarios described here can be combined and mixed to meet your specific requirements. JAAS and login modules provide a reasonably flexible framework with which you can work. For example:
Identity assertion with inbound identity mapping
The asserted identity is picked up on the target server side and is used to perform inbound identity mapping.
Identity assertion using custom token object with inbound identity mapping
The asserted identity is transmitted inside a custom token object, which is then picked up on the target server and used in an inbound identity mapping module.
Identity assertion using custom token object and server-side identity assertion
The asserted identity is transmitted in a custom token object, which is picked up by the server-side identity assertion login module and used to assert the identity.
Many other combinations are possible. Which scenarios to combine depends on the requirements. The Login scenarios and requirements matrix included with this article can help you design the best login solution for for applications. In this spreadsheet:
- The first column lists all the login scenarios described in this article.
- The header lists the configuration and application requirements for each scenario.
- There are several notes made at the bottom of the matrix (numbered list), which you should be sure to understand before you decide on a solution.
The matrix can help you:
- Find or check the necessary configuration and application requirements for a specific login scenario.
- Browse through the scenarios to find the right one by matching the requirements for your solution.
- Browse the configuration and application requirements to find the right scenario or combination of scenarios for your solution.
Trust Association Interceptor for Web inbound login
This article has not gone into details about the WebSphere Trust Association Interceptor (TAI), mainly because it has little to do with JAAS. However, since we are concerned about login -- Web application login in particular, imagine the Trust Association Interceptor as a special type of inbound login module in front of the Web container. This module literally intercepts the incoming Web (HTTP) request and performs a login, similar to what a login module would do. After the login, it passes an identity, not a subject, as a result. Later, this identity is used to create the subject. The Trust Association Interceptor is invoked just before the WEB_INBOUND system login configuration.
See the WebSphere Application Server Information Center for more information about the Trust Association Interceptor.
This section describes how to setup a WebSphere Application Server environment for testing the sample code provided with this article. Figure 4 shows the simplest setup for testing these scenarios.
Figure 4. Testing the scenarios
In this test environment:
- There are three nodes, two application servers, and one developer node.
- Each application server node has an LDAP server installed as a user registry. Some of the scenarios require two different user registries to work with. When only one user registry is required (both application servers sharing the same) then use the LDAP server from the appsrv01 node (this user registry has both server IDs).
- There is no deployment manager in this environment.
- There is no need to configure cell(s) and the configuration tasks are easily manageable for two applications servers using two browser sessions.
- The users used in the samples are also listed on the diagram. Names can be altered in any way as needed, just make sure that all names are different between the user registries for testing purposes.
- There are two enterprise applications, one for each application server: SenderApplication, TargetApplication.
- There are also three libraries (JAR files) that must be installed on the application servers. Figure 5 is a deployment diagram to help with the distribution of the applications and libraries.
Figure 5. Application deployment for sample environment
Notice that there is only one library file (JAR) for all the custom login modules. This is to make the deployment easier for the samples. Typically, your code would be separated like this:
- System login modules and utility classes (for example, callback handlers and callbacks) for the sending server. These are then deployed in the sending server's lib directory.
- Application login modules and utility classes for the sending server. These are stored as a utility module in the enterprise application deployed on the sending server.
- System login modules and utility classes for the target server. These are deployed in the target server's lib directory.
- Application login modules and utility classes for the target server. These are stored as a utility module in the enterprise application deployed on the target server.
- Shared Login modules and utility classes, used by both servers, are deployed in the lib directory of both servers.
- Shared classes for login modules (such as tokens) are also deployed in the lib directory of both servers.
The application server configuration for each scenario is different. The best way to test the scenarios is to configure the application server for a specific scenario as needed, then go back to the original, default WebSphere Application Server security configuration (or "un-configure") before trying or testing a new scenario.
Once a scenario is configured and deployed, start up the servers, and then use this URL to access the index page, which is also a hub for all the scenarios. http://appserver01.demo.ibm.net:9080/sender/index.html. Use the user names from the sending server's user registry to login when the Web application requires. Check the SystemOut.log file for details about the actual test and what the code is doing. The sample code generates an extensive amount of informational level output to read.
Think twice before you start writing login modules to customize your application server. Check the available login options for WebSphere Application Server, because it is possible that you might be able to use one of them without further customization. Try first to find a solution based on configuration, without writing custom code. If you cannot avoid writing a custom login solution, it is imperative that you know what you are doing. You must make sure that your custom login does not break the applications already installed and running on the application server. Don't merely test your code: review your code and get it reviewed by others. You can never be cautious enough when it comes to custom security solutions.
Although this article was written for RMI/IIOP and CSIv2, you may have already realized that the concept and most of the techniques for login are similar for other protocols, including HTTP, WS-Security, and so on.
| Description | Name | Size | Download method |
|---|---|---|---|
| Sample application | LoginScenarios-ProjectInterchange.zip | 54 KB | HTTP |
| Login scenario spreadsheet | LoginMatrix.pdf | 44 KB | HTTP |
Information about download methods Get Adobe® Reader®
-
Sun's JAAS documentation
-
WebSphere Application Server Information Centers (all versions)
-
IBM WebSphere Application Server V6.1 Security Handbook, Redbook SG24-6316
Peter Kovari is part of the IBM Software Group Services organization in Hursley, UK. His responsibilities span from specialist areas to various IT architectures. He is often traveling to customer locations to help clients with the adoption of IBM's software portfolio. Formerly, Peter worked for ITSO in Raleigh, NC, as an IT specialist, project leader, and technical author writing IBM Redbooks® with other IBM professionals from all over the world.




