Enterprise Authentication Integration

The ZENworks Mobile Workspace SDK provides API to delegate user authentication to any type of enterprise authentication server such as LDAP servers, RSA servers or RADIUS based servers. However, for backward compatibility, LDAP AD authentication has been kept has default authentication module.

JAAS Login module

The authentication is based on JAAS standards which delegates authentication to the JEE application server, and allows using pre-defined modules or defining your own custom module by implementing the LoginModule interface.

JAAS Context name

The JAAS context name parameter must be referenced in ZENworks Mobile Workspace configuration with the name of the JAAS context (also known as "realm") in which the custom LoginModule is configured. Typically, the LoginModule is provided and configured by the Java Entreprise (JEE) application server.

JAAS Callback handler

The JAAS LoginModule (either default or custom) is initialized by default with a CallbackHandler that provides the username and password entered by the end-user as a NameCallback and a PasswordCallback , respectively to the LoginModule. If configured, the LoginModule does not require other credentials, the default JAAS CallbackHandler class name field can be left blank. If the LoginModule requires additional configuration (for example a RADIUS LoginModule requires server address and shared key parameters), a CallbackHandler with the following constructor arguments must be provided with the LoginModule and referenced in ZENworks Mobile Workspace configuration:

public MyCustomCallbackHandler(String userName, char[] password);

The custom CallbackHandler is responsible to load its additional parameter(s) from any source, such as configuration file, JNDI object, system property, etc…

Enterprise Group Integration

The ZENworks Mobile Workspace SDK provides API to synchronize security groups against any data sources such as LDAP servers, databases or flat files. However, for backward compatibility, LDAP (ActiveDirectory-compatible) synchronization has been kept as default synchronization module. Group synchronization works with a proprietary interface provided by the ZENworks Mobile Workspace SDK, it does not rely on roles that the LoginModule may provide when authenticating users, although this interfaces uses Groups.

Synchronization parameters interface

Even if all parameters can be hard-coded in the synchronization manager or retrieved from a custom data source, ZENworks Mobile Workspace SDK provides an integrated and flexible way to retrieve them. The administration console allows IT manager to set several parameters whose can therefore be used by a custom synchronization manager:

  • URL/Path: This parameter can be used to provide an URL or a path to the data source such as LDAP URL, file path or database connection URL.

  • Username: This parameter is commonly used to provide a username needed to connect the synchronization data source.

  • Password: This parameter is commonly used to provide a password needed to connect the synchronization data source.

Developers of custom adapters will be able to access these parameters through the GroupSynchronizationParameter interface. ZENworks Mobile Workspace synchronization mechanism does not directly use Principal JAAS class. For comfort purpose of the administration console, Principal class has been extended by SENSEPrincipal which force developers to return the first name and the last name of a principal. This interface is discussed later as part of the synchronization manager.

Synchronization manager interface

This is the main class of the synchronization mechanism which will be dynamically loaded and used by the ZENworks Mobile Workspace Security server to synchronize groups and users. Based on interface (ch.sysmosoft.sense.common.synchronization.GroupSynchronizationManager), four methods must be implemented to fulfill the contract:

  • void init(GroupSynchronizationParameter groupSynchronizationParameter): As its name indicate, this method aims to initialize the synchronization manager with the given parameters. These parameters are those previously set through the administration console.

  • boolean checkParameters(): This method return a boolean to indicate if the parameter set through the administration console are correct or not. It is up to the developer of the custom module to do appropriate check(s) (parameter required, right URL/Path, etc). This method will be used by the administration console to delegate the check and show the IT manager whether parameters are correct or not.

  • List<Group> getGroups(): Used in the group editing user interface, this method must return the list of JAAS groups (java.security.acl.Group) allowed to be synchronized by ZENworks Mobile Workspace. The name cannot be null or empty as it will be used to retrieve principals in that group. It means no member (principal) of this group will be used directly. Only principal(s) returned by the method List<SENSEPrincipal> getPrincipals(Group selectedGroup) will be synchronized.

  • List<SENSEPrincipal> getPrincipals(Group selectedGroup): When a group is selected in the user interface, this method is called to retrieves members of the selected group. In the case of new group creation, ZENworks Mobile Workspace synchronization mechanism will add all users to the security group. If we need to synchronize an existing group, ZENworks Mobile Workspace will compare both groups and synchronize the existing group against the reference group. The principal’s name will be used as username and displayed as it in the administration console. User without user name or already member of different group will not be synchronized.

Synchronization manager example

The first step of implementing a custom synchronization manager is to define objects whose are implementing JAAS standards. The following class defines a simple group which must be initialized with a name. Keep in mind that the name is the only attribute used by ZENworks Mobile Workspace synchronization mechanism. Members will not be retrieved using the members() method as they will be retrieved later through the getPrincipals() method of the synchronization manager:

Code 1. Group
public class SimpleGroup implements Group {

    private String name;

    public SimpleGroup(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public boolean addMember(Principal user) {
        return false;
    }

    public boolean isMember(Principal member) {
        return false;
    }

    public Enumeration<? extends Principal> members() {
        return null;
    }

    public boolean removeMember(Principal user) {
        return false;
    }
}

The following class defines a simple user based on SENSEPrincipal interface. The name is important as it will be used for identification and authentication when establishing a ZENworks Mobile Workspace security session:

Code 2. Principal
public class SimpleUser implements SENSEPrincipal {

    private String name;
    private String firstName;
    private String lastName;

    public SimpleUser(String name, String firstName, String lastName) {
        this.name = name;
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public String getName() {
        return name;
    }
}

Once JAAS objects have been defined, a custom synchronization manager can be created. The following rough example manager:

  1. Keeps a reference on the parameters

  2. Checks if all parameters have been set (even if not needed later)

  3. Returns a static group list

  4. Returns a static user list if the group is the one return by the getGroups() method.

Code 3. Group synchronization
public class MyCustomSynchronizationManager implements GroupSynchronizationManager {

    private static final String GROUP_NAME = "My test group";
    private GroupSynchronizationParameter param;

    public void init(GroupSynchronizationParameter param) {
        this.param = param;
    }

    public boolean checkParameters() {
        return (param.getPassword() != null && !param.getPassword().isEmpty())
            && (param.getUrl() != null && !param.getUrl().isEmpty())
            && (param.getUsername() != null && !param.getUsername().isEmpty());
    }

    public List<Group> getGroups() {
        return Arrays.asList(new SimpleGroup(GROUP_NAME));
    }

    public List<SENSEPrincipal> getPrincipals(Group group) {
        if (GROUP_NAME.equals(group.getName())) {
            return Arrays.asList(new SimpleUser("test_login","Test","Test"));
        } else {
            return Collections.emptyList();
        }
    }
}

ZENworks Mobile Workspace Configuration

Once the custom modules have been developed, they must be referenced in the classpath of the ZENworks Mobile Workspace application. Then, the corresponding domain in the security server administration console must be configured. Full description can be found in the ZENworks Mobile Workspace Security Server: Administration Guide. Here are the summary steps:

  1. Log in the ZENworks Mobile Workspace administration console as Superadmin.

  2. Click on the DOMAINS menu.

  3. Edit the desired domain (or create a new one).

  4. Go under the Identities tab.

  5. Select the Custom authentication and synchronization method.

  6. Set the Context name with the custom JAAS Context name.

  7. Set the Custom callback handler class name with the name of the custom JAAS Callback handler.

  8. Set the Custom class name with the name of the custom implementation of the Synchronization manager interface.