Active directory

Active directory

Functionality

The Active Directory Adapter allows TrustBuilder to perform various operations against an Active Directory server.

Configuration

The adapter configuration specifies the adapter instance (adapter id), the global load-balancing settings and the configuration of one or more servers.

Parameter
Description
Required
AdapterUniqueID Unique name assigned to this adapter; the name is used to reference the adapter in the workflow.
The ID has following requirements:
  • START with a letter or _ (underscore)
  • FOLLOWED by a combination of following characters: Letter, Number, '.' (dot), '-' (dash), '_' (underscore)
x
Type The type of server to connection to. Possible values are RO and RW (default is RW).
  • RO: Read-Only
  • RW: Read-Write
x
Host Settings:
Address URL or IP of the backend LDAP Server x
Port TCP Port of the backend LDAP Server x
Transport Settings:
ConnectionPool Allow the use of a connection pool. The poolsize is set at the JVM level
protocol SSL protocol version to be used for connection to the backend. Valid options are: none, default, sslv3, tlsv1 or was
  • no SSL (protocol = none)
  • default SSL settings (protocol = default)
  • explicit SSL settings (protocol =sslv3 or tlsv1)
  • WebSphere setting (protocol = was)

If the selected protocol is none. None of the following Security Settings are required. However if you do place them in the security element, they should be correct
x
DN DN to authenticate with, this user must have sufficient rights. It will only be used when no credentials are passed in the request. x1
Password Type the password of the DN . This will be automaticly encrypted when saving the adapter. x1

1 if the selected protocol is none. None of the following Security Settings are required. However if you do place them in the security element, they should be correct Workflow Settings

Workflow Settings

A request for the adapter is prepared by specifying the following properties/scripts in the adapter activity: * Input Property: the variable containing the instructions the adapter have to execute * Output Property: the variable the adapter will store the response in after execution * Before Adapter Script: script that will be executed before calling the adapter * After Adapter Script: script that will be executed after the adapter fulfilled its task

Request - API

Common Request Attributes

The following list gives an overview of the attributes used in the request-API; examples on how to use these attributes can be found in the examples throughout this chapter.

Option Description
baseDN Use baseDN as the starting point for the search action
Credentials Username and password overriding these specified in the "adapter configuration"
Scope Specifies the search scope:
  • LDAP_BASE
  • LDAP_ONE
  • LDAP_UNKNOWN
    Search the entire subtree rooted at the named object. If the named object is not a Directory Context, search only the object. If the named object is a Directory Context, search the subtree rooted at the named object, including the named object itself. The search will not cross naming system boundaries. The NamingEnumeration that results from search() using
  • LDAP_SUB:
Filter Search filters enable you to define search criteria and provide more efficient and effective searches
Attributes The set of attributes that should be returned as a result of a search action. All the attributes are returned if not specified.
Bindings The data that must be added/updated as part of an ADD/MODIFY-action; a data type (LDAP_STRING or LDAP_BINARY) per attribute can be given along.
IncludeValues If set to yes: Retrieve attributes only (no values). This is useful when you just want to see if an attribute is present in an entry and are not interested in the specific values.
defaultType Indicates the data type of the attributes as a result of a search action; LDAP_STRING is default behavior if not specified.
  • LDAP_STRING: Return as strings
  • LDAP_BINARY: return as base64 encoded binary
Authenticate

LdapAuthenticateRequest Tries an LDAP-bind with the specified DN and corresponding password.

tb.ldapAuthenticateRequest(dn, password); 

LdapAuthenticateSearchRequest The search-request, resulting in one DN, is followed by an authenticate-request by combining: 1. The DN as a result of the search action, 2. the pasword given along in the parameter "password: "

var credentials = {'user':'dn','password':"itsme"};
tb.ldapAuthenticateSearchRequest({
 baseDn: 'dn',
 password: 'itsme',
 scope: LDAP_ONE,
 filter: "cn=filter",
 credentials:credentials,
});
Password

LdapChangePasswordRequest

The LdapChangePasswordRequest allows clients to change the password of given DN after verifying the current password. The actual operation is performed using the adapter's adminstrator credentials.

tb.ldapChangePasswordRequest(dn,oldPassword,newPassword) 

LdapSetPasswordRequest

The LdapSetPasswordRequest allows clients to set the password of given DN. The actual operation is performed using the adapter's adminstrator credentials.

tb.ldapSetPassword(dn,password) 
Delete

LdapDeleteRequest

The ldapDeleteRequest is used to delete a given object from the LDAP. The bind uses the adapter's adminstrator credentials, if a bindDN/bindPassword is not specified.

tb.ldapDeleteRequest(dn-to-delete,bindDN,bindPassword) 
Modify

LdapModifyRequest

The LdapModifyRequest allows the client to modify one or more attributes of a given DN. Three modify actions are supported: * ADD: adding values to a multi-valued attribute or setting the value of an empty single-valued attribute * MODIFY: changing the value(s) of an attribute * DELETE: deleting values from a multi-valued attribute or clearing a single-valued attribute.

These operations may be combined into a single request as illustrated below.

tb.ldapModifyRequest({
    dn: 'dn',
    scope: scope,
    filter : "(objectClass = inetOrgPerson)",
    modifications => COMPLETE EXAMPLE.
 });

Response - API

Common Properties

The response API can be applied to the variable specified in the output property (see Workflow Settings): 1. to verify whether the action performed by the adapter was successful, 2. to query for the data returned by the adapter.

All responses have four properties in common:

  • status Status flag indicating whether the response is ok (0) or not (1).
  • substatus Response specific number indicating what the problem was, eg. http status code
  • message Response specific message in case there was a problem (can be null)
  • rc Return Code, a human readable code based on the substatus

The status flag indicates whether a request was valid yes or no; consequently, the message or return code (rc) can be used to give the end-user a reasonable explanation or send the information to the underlying logging system.

Adapter Specific Properties

The response from the active directory is the same as for the ldap adapter. please refer to that adapter for specific properties.

Response Codes

All response codes are inherited from the ldap adapter so you can find the extensive list there. Additional Notes

Connection Pool There is no option to specify the size of the connection pool. The JNDI interface only allows to set the connection pool size at the JVM level.

SSL In case the configuration specifies an explicit SSL protocol, the necessary stores (both in case of mutual SSL), store format (JKS or PKCS12) and password file must be set. Note that the chosen protocol may or may not be supported by a specific provider. The default SSL settings typically use the JVM security settings defined in system properties, but this need not be so. For instance, WebSphere allows administrators to configure the mapping of LDAP URLs onto SSL configurations (if no settings are defined at the JVM level),

Load Balancing A server is either of type RW (read-write) or of type RO (read-only), with RW the default type. Read-write servers accept all request types, whereas read-only servers only accept non-destructive operations (authenticate and search requests). In order not to complicate the load-balancer algorithm, the LdapAdapter uses a secondary load-balancer for write requests if not all servers accept write requests. The adapter then delegates requests to the proper load-balancer. Note that when two load-balancers are used, each balancer keeps track of server penalties independently to one another.

Example

Connection Settings For this example we are searching for a specific user against the active directory. We use for this purpose his windows login name (sAMAccountName). The Active directory adapter is configured to point to the Active Directory Server

Workflow Settings We have created for this example a very basic workflow that is searching for a fixed user. From the Endpoint the workflow is going to the AD Adapter. The before script is used to make the request to the adapter. The Script function is used to validate the response for errors and create a result to the endpoint.

Making the request In the before Adapter script we made a function ldapwinadSearch. This function is going to search for the user 'test' under a specific DN in the ldap. The user has different attributes in ldap, for Windows most common used is the sAMAccountName. If we view the LDIF of this user we see also the objectclasses. We left out some key/values in the example for readability.

LDIF of user test
dn: CN=test,CN=Users,DC=bat,DC=po,DC=securit,DC=biz
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: user
cn: test
instanceType: 4
objectCategory: CN=Person,CN=Schema,CN=Configuration,DC=bat,DC=po,DC=securit,DC=biz
accountExpires: 9223372036854775807
displayName: test
distinguishedName: CN=test,CN=Users,DC=bat,DC=po,DC=securit,DC=biz
givenName: test
name: test
objectGUID:: c5NSTNQMU0WC2RQQSsTahA==
objectSid:: AQUAAAAAAAUVAAAAjHzyk5Op+wC7OboCXgQAAA==
primaryGroupID: 513
pwdLastSet: 129796511806093750
sAMAccountName: test
sAMAccountType: 805306368
userPrincipalName: test@bat.po.securit.biz

So we create the ldapwinadSearch function to search the user 'test' :

//ldapwinadSearch
function ldapwinadSearch(workItem) {
    var ldapreq = {
        dn: "CN=Users,DC=bat,DC=po,DC=securit,DC=biz",
        filter: "sAMAccountName=test", //This will search for every inetOrgPerson object
        scope: LDAP_SUB
    };
    workItem.request = tb.ldapSearchRequest(ldapreq);
}

This function will send the workItem.request variable to the AD adapter This request will be visible in the TRACE logging :

Logging
[WebContainer : 8] TRACE b.s.t.a.server.SingleServerPool - Sending request to winad034 [1]
[WebContainer : 8] TRACE b.s.t.adapter.ldap.JndiServer - Searching for sAMAccountName=test within base CN=Users,DC=bat,DC=po,DC=securit,DC=biz [1]
[WebContainer : 8] TRACE b.s.t.adapter.ldap.JndiServer - Binding with CN=Administrator,CN=Users,DC=bat,DC=po,DC=securit,DC=biz [1]
[WebContainer : 8] TRACE b.s.t.adapter.ldap.JndiServer - Binding via pool [1]
[WebContainer : 8] TRACE b.s.t.a.server.SingleServerPool - Request successfully completed [1]

Handling the response The AD Adapter now searches for the user, the response must be parsed by a script function. This can be a After Adapter Script', Condition or Script. We handle the response in this example as a After Adapter Script with the ldapwinadAfterSearch function.

function ldapwinadAfterSearch(workItem) {
    var returned = workItem.response;
    log(returned, "Aftersearch");
    workItem.entryReturned = workItem.response.getEntries();
    workItem.entryUsed = workItem.entryReturned[0];
    log(workItem.entryReturned[0], "EntryReturned");
    switch (workItem.response.status) {
        case 0:
            switch (workItem.response.substatus) {
                case 0:
                    break;
                case 2:
                    log("A challenge was sent by the Ldap server");
                    break;
            }
            break;
        default:
            log("Active Directory LDAP has encountered an error");
            break;
    }
}

The log function is here helping to debug the returned object. In the logfile this will give something like :

Logging
[WebContainer : 8] TRACE Engine.ScriptLogger - [ Aftersearch ] LdapResponse (
    status = 0, substatus = 0
    message =
    entry (
        objectClass (value = top, value = person, value = organizationalPerson, value = user)
        cn (value = test)
        givenName (value = test)
        distinguishedName (value = CN=test,CN=Users,DC=bat,DC=po,DC=securit,DC=biz)
        instanceType (value = 4)
  displayName (value = test)
        uSNCreated (value = 20534)
        uSNChanged (value = 34980)
        name (value = test)
        objectGUID (value = sLSEJ)
        userAccountControl (value = 66048)
        badPwdCount (value = 1)
        codePage (value = 0)
        countryCode (value = 0)
  primaryGroupID (value = 513)
        objectSid (value = ?^)
        logonCount (value = 2)
        sAMAccountName (value = test)
        sAMAccountType (value = 805306368)
        userPrincipalName (value = test@bat.po.securit.biz)
        objectCategory (value = CN=Person,CN=Schema,CN=Configuration,DC=bat,DC=po,DC=securit,DC=biz)
    )

We are putting the first returned DN in the workItem.entryUsed variable. For this we first used the function getEntries() and from here we selected the first entry. ( workItem.entryReturned[0] ) The next script function is used to create the output based on the adapter status and giving back the DN of the user found.

[WebContainer : 8] TRACE Engine.ScriptLogger - [ EntryReturned ] [ CN=test,CN=Users,DC=bat,DC=po,DC=securit,DC=biz ] [1]

winadOutput
function winadOutput(workItem) {
    var entry = workItem.entryUsed;
    var bodygood = "<h1>WinAD OK " + entry + " </h1>";
    var bodybad = "<h1>WinAD NOT OK</h1>";
    var respcookies = null;
    var respheaders = null;
    if (workItem.response.status == 0) {
        workItem.output = tb.generateResponse(bodygood,/*defaults:, null , null, 200*/);
    }
    else {
        workItem.output = tb.generateResponse(bodybad, respheaders, respcookies, 501);
    }
}

In this function we set the DN entry found in the body after the a small message. If the adapter had no errors (status ==0) we show the ok page. Otherwise we show a bad page with a response error. In the logfile this will be shown as output :

Logging
[WebContainer : 8] TRACE Engine.WorkItem - set ___OUTPUT___=EndpointResponse (
    status = 200, substatus = 0
    Status = 200
    <h1>WinAD OK [ CN=test,CN=Users,DC=bat,DC=po,DC=securit,DC=biz ] </h1>
) [1]

This will complete the workflow and the output is returned.

Mock response function

function searchDevice(){
    return {
        status:0,
        substatus:0,
        getEntries: function(){
            return [{
                dn: 'cn=koen,o=securit',
                getAttributeValue: function(item){
                    switch (item){
                        case 'tfDevicePIN': return '123';
                        case 'sitDN': return 'cn=koen,o=securit';
                        case 'tfRegCode': return '123';
                        case 'tfDeviceToken': return '123';
                        case 'tfDevicePlatform': return 'ios';
                    }
                }
            }];
        }
    }
}
Was this article helpful?
0 out of 0 found this helpful
Have more questions? Submit a request

Comments

0 comments

Please sign in to leave a comment.