
AS Java enables you to authenticate remote clients that establish Remote Method Invocation (RMI) connections to AS Java. Authentication of remote clients is pluggable and can use several types of security credentials, including logon tickets.
AS Java can authenticate remote clients using the following methods:
For this remote logon method, the JNDI policy configuration is used for authentication for both the remote client and the server. You can use this logon method for scenarios when the remote client requires access to the JNDI to gain access to server-side objects.
Authentication flow
Remote clients can authenticate to AS Java when they request a new InitialContext . This can be done by setting security credentials in the properties that are given to the initial context instance. When the close() method is called on this initial context, the authenticated user is logged out.
If the client application creates more than one initial context instance, each of these contexts can perform or not perform authentication depending on whether the security credentials are passed on, and whether they have already been authenticated. The following cases are possible:
Standard property names for authentication credentials
You can use standard property names to set the user ID and password for authentication credentials in initial context properties. These standard property names are defined in javax.naming.InitialContext . They use the following constants:
Non-standard property names for authentication credentials
The logon modules that are configured for the authentication stack of the JNDI policy configuration may request specific credentials for successful authentication. Therefore, the security credentials (the property names) that you can pass depend on the logon modules in the JNDI authentication stack.
You can use non-standard credentials by entering property names in the following format:
sap.security.credential.<credential_type>.<credential_name>
where credential_type and the credential_name identify the type and the name of the security credential that is requested by the logon module.
For example, EvaluateTicketLoginModule requests that the client provides an SAP logon ticket by setting, in HttpGetterCallbackHandler, the type equal to HttpCallback.COOKIE and the name - MYSAPSSO2 . Therefore, in the initial context properties, the client application has to set the user ticket with the property name sap.security.credential.2.MYSAPSSO2 .
You can use the property sap.security.callback.handler to specify a callback handler that must be used for authentication of the remote client at logon to the server.
In addition to setting this property for the InitialContext, you need to adjust the corresponding login module stack that the Naming service uses during the authentication process. More information about non-standard properties: RMI-P4 Specific InitialContext Properties .
This remote logon scenario uses the JAAS authentication mechanisms of AS Java to protect access and enables you to configure authentication to apply specifically to the remote client. In this case, logon is performed using a RemoteLoginContext that is passed a CallbackHandler for the security credentials that are provided using JAAS callbacks.
Also, you have to maintain a property named RemoteLoginWhitelist. This property contains a comma separated list with names of policy context configurations allowed for remote login.
To achieve a secure transmission of the supplied logon details, such as user name and password or certificate, you must use a remote P4 protocol over a secure socket layer (SSL) with a secure server port that requires a client certificate:
For more information about configuring the Internet Communication Manager (ICM) parameters to enable the use of SSL for the P4 port, see Maintaining ICM Parameters for Using SSL .
Never do that if you do not have actual P4SEC port configured as described above or do not have P4 port protected at network level.
You can also use a RemoteLoginContext constructor to pass a security policy configuration for use in the authentication. In this case you have to adjust the login modules in the authentication stack of the passed policy configuration for the authentication mechanism you use.
The remote client has to provide a callback handler for retrieving the requested credentials in an application-specific way. The CallbackHandler has to support the following interfaces that are provided by AS Java:
For more information, see Protecting Java Web Applications .
Authentication Flow
For an overview of the authentication flow for this case, see the figure below:
Creating Callback Handler
The code sample below shows an example of how to make a callback handler:
public class TemplateCallbackHandler implements CallbackHandler {
public void handle(Callback[] callbacks) throws IOException,
UnsupportedCallbackException {
for (int i = 0; i < callbacks.length; i++) {
if (callbacks[i] instanceof NameCallback) {
String userName = getUserName();
((NameCallback) callbacks[i]).setName(userName);
} else if (callbacks[i] instanceof PasswordCallback) {
char[] password = getPassword();
((PasswordCallback) callbacks[i]).setPassword(password);
} else if (callbacks[i] instanceof HttpGetterCallback) {
// This is a general type of callback, so it can be used
// for various types of credentials.
HttpGetterCallback getterCallback = (HttpGetterCallback) callbacks[i];
/**
* The type and the name identify what kind of credential is
* requested by the logon module. Possible values for the type
* are defined in com.sap.engine.lib.security.http.HttpCallback.
* CallbackHandler can understand none, some, or all of them.
* It also may be extended with other types if the logon module
* that is used along with this callback handler requests them.
* For SAP Logon Ticket the identifiers are:
* type = HttpCallback.COOKIE, name = "MYSAPSSO2".
*/
/**
* The logon module has set the type and the name of the
* security credential that is needed for the authentication.
*/
byte type = getterCallback.getType();
String name = getterCallback.getName();
// CallbackHandler gets the specified credential.
Object value = getCredentialValue(type, name);
// The credential is passed back to the logon module.
getterCallback.setValue(value);
} else if (callbacks[i] instanceof HttpSetterCallback) {
/**
* This type of callback is used by the logon module to
* give some credentials back to the client. For example,
* after the user is authenticated successfully with user
* name and password, CreateTicketLoginModule could create
* and give back SAP Logon Ticket for that user.
*/
HttpSetterCallback setterCallback = (HttpSetterCallback) callbacks[i];
byte type = setterCallback.getType();
String name = setterCallback.getName();
Object value = setterCallback.getValue();
storeCredential(type, name, value);
} else {
throw new UnsupportedCallbackException(callbacks[i], "Unsupported callback!");
}
}
}
/**
* Retrieves the user name in an application-specific way.
*/
private String getUserName() {
...
}
/**
* Retrieves the user password in an application-specific way.
*/
private char[] getPassword() {
...
}
/**
* Retrieves other security credentials that are required for
* the application authentication.
*/
private Object getCredentialValue(byte type, String name) {
...
}
/**
* Stores the given security credentials of the client.
*/
private void storeCredential(byte type, String name, Object value) {
...
}
/**
* Calls the CallBackHandler and sets the RemoteLoginContext.
*/
public static void main (String [] args) throwsException{
TemplateCallbackHandler callback_handler = new TemplateCallbackHandler ();
RemoteLoginContext loginCtx = new RemoteLoginContext(callback_handler, <authn_policy_name>, "", <as_java_host>, <trusted_p4sec_port>);
loginCtx.login();
loginCtx.logout();
}
}