Configuring the K2 LDAP User Manager

Use this information to configure the K2 LDAP user managers settings. You can edit the sample script for your environment and use it to configure your LDAP user manager.

There are many settings due to the nature of LDAP and its various implementations. Each user directory implements different capabilities and queries for one LDAP provider may not work for another. Once you understand these settings, you can configure the LDAP user manager to work with your specific LDAP identity store.

If available, the K2LDAP label is visible in the K2 Management site under the Users node.

Sample SecurityLabels SQL Script

The following example is for the fictitious Denallix.com domain. You must change some of the values below to match your environment. The downloadable script file includes this XML and running the script inserts it into the SecurityLabels table of the K2 database.

Copy

Sample SecurityLabels SQL Script

-- K2 LDAP User Manager (Forms - Setup).sql
    -- sample script for creating a K2 LDAP user manager that uses the SourceCode.Security.Providers.LdapProvider.Forms.Ldap provider

    -- DECLARATIONS
    DECLARE @SecurityLabelName NVARCHAR(20) = 'K2FORMS'; --Update as needed
    DECLARE @XmlConfig XML = 
    '<AuthInit>
    <LdapConnection LdapServer="dlx.denallix.com" LdapServerPort="389" LdapSsl="false" LdapAuthTypeConnect="Negotiate" LdapAuthTypeAuthenticateUser="Negotiate" LdapResolveAuthenticationUserToDistinguishedName="false" LdapAutoBind="false" LdapScope="Subtree" LdapConnectIntegrated="true" LdapConnectUserName="" LdapConnectUserPassword="" LdapTimeout="0" LdapProtocolVersion="3" LdapServerCertificatePath="" />
    <LdapUserBaseObject>OU=FORMS,DC=QA,DC=COM</LdapUserBaseObject>
    <LdapUserSearchFormatString>userPrincipalName={0}</LdapUserSearchFormatString>
    <LdapUserGroupSearchFormatString />
    <LdapUserAttributes>
    <K2LdapMapping K2Name="ID" LdapName="userPrincipalName" ObjectType="System.String" />
    <K2LdapMapping K2Name="Name" LdapName="userPrincipalName" ObjectType="System.String" />
    <K2LdapMapping K2Name="Description" Multiline="true" LdapName="description" ObjectType="System.String" />
    <K2LdapMapping K2Name="Email" LdapName="mail" ObjectType="System.String" />
    <K2LdapMapping K2Name="DistinguishedName" LdapName="distinguishedName" ObjectType="System.String" />
    <K2LdapMapping K2Name="ObjectSID" FullOnly="true" LdapName="objectSID" ObjectType="System.String" />
    <K2LdapMapping K2Name="CommonName" LdapName="cn" ObjectType="System.String" />
    <K2LdapMapping K2Name="UserPrincipalName" LdapName="userPrincipalName" ObjectType="System.String" />
    <K2LdapMapping K2Name="Manager" FullOnly="true" LdapName="manager" ObjectType="System.String" SearchQuery="(&amp;(objectClass=Person)(objectCategory=User))" SearchResultProperty="userPrincipalName" />
    <K2LdapMapping K2Name="SipAccount" LdapName="msRTCSIP-PrimaryUserAddress" ObjectType="System.String" />
    <K2LdapMapping K2Name="DisplayName" LdapName="displayName" ObjectType="System.String" />
    <K2LdapMapping K2Name="TelephoneNumber" LdapName="telephoneNumber" ObjectType="System.String" />
    <K2LdapMapping K2Name="Mobile" LdapName="mobile" ObjectType="System.String" />
    <K2LdapMapping K2Name="HomePage" LdapName="wWWHomePage" ObjectType="System.String" />
    <K2LdapMapping K2Name="FaxNumber" LdapName="facsimileTelephoneNumber" ObjectType="System.String" />
    <K2LdapMapping K2Name="HomePhone" LdapName="homePhone" ObjectType="System.String" />
    <K2LdapMapping K2Name="IPPhone" LdapName="ipPhone" ObjectType="System.String" />
    <K2LdapMapping K2Name="StreetAddress" LdapName="streetAddress" ObjectType="System.String" />
    <K2LdapMapping K2Name="City" LdapName="l" ObjectType="System.String" />
    <K2LdapMapping K2Name="Country" LdapName="c" ObjectType="System.String" />
    <K2LdapMapping K2Name="State" LdapName="st" ObjectType="System.String" />
    <K2LdapMapping K2Name="Title" LdapName="title" ObjectType="System.String" />
    <K2LdapMapping K2Name="Department" LdapName="department" ObjectType="System.String" />
    <K2LdapMapping K2Name="Company" LdapName="company" ObjectType="System.String" />
    <K2LdapMapping K2Name="Office" LdapName="physicalDeliveryOfficeName" ObjectType="System.String" />
    <K2LdapMapping K2Name="ManagedUsers" FullOnly="true" LdapName="managedUsers" SearchQuery="(&amp;(objectClass=Person)(objectCategory=User))" SearchResultProperty="userPrincipalName" ObjectType="System.Collections.ArrayList" />
    <K2LdapMapping K2Name="Groups" FullOnly="true" LdapName="memberOf" SearchQuery="(objectCategory=Group)" SearchResultProperty="userPrincipalName" ObjectType="System.Collections.ArrayList" />
    </LdapUserAttributes>
    <LdapGroupBaseObject>OU=FORMS,DC=QA,DC=COM</LdapGroupBaseObject>
    <LdapGroupSearchFormatString>userPrincipalName={0}</LdapGroupSearchFormatString>
    <LdapGroupMemberSearchFormatString />
    <LdapGroupAttributes>
    <K2LdapMapping K2Name="ID" LdapName="userPrincipalName" ObjectType="System.String" />
    <K2LdapMapping K2Name="Name" LdapName="cn" ObjectType="System.String" />
    <K2LdapMapping K2Name="Description" Multiline="true" LdapName="description" ObjectType="System.String" />
    <K2LdapMapping K2Name="Email" LdapName="mail" ObjectType="System.String" />
    <K2LdapMapping K2Name="DistinguishedName" LdapName="distinguishedName" FullOnly="true" ObjectType="System.String" />
    <K2LdapMapping K2Name="ObjectSID" LdapName="objectSID" FullOnly="true" ObjectType="System.String" />
    <K2LdapMapping K2Name="Member" LdapName="member" FullOnly="true" SearchQuery="(&amp;(objectClass=Person)(objectCategory=User))" SearchResultProperty="userPrincipalName" ObjectType="System.Collections.ArrayList" />
    </LdapGroupAttributes>
    </AuthInit>' -- XML configuration for the LDAP provider, see K2 Help for more information on configuration values
    DECLARE @SecurityLabelID UNIQUEIDENTIFIER = NEWID();
    DECLARE @AuthSecurityProviderID UNIQUEIDENTIFIER = NEWID(); --Assigning new GUID
    DECLARE @AuthInit XML = @XmlConfig;
    DECLARE @RoleSecurityProviderID UNIQUEIDENTIFIER = @AuthSecurityProviderID;
    DECLARE @RoleInit XML = @XmlConfig;
    DECLARE @DefaultLabel BIT = NULL; --1 = true, NULL and 0 = false
    DECLARE @ProviderClassName NVARCHAR(200) = 'SourceCode.Security.Providers.LdapProvider.Forms.Ldap';
    DECLARE @SPProviderID UNIQUEIDENTIFIER;

    -- UPDATE TABLES
    DELETE FROM [k2].[HostServer].[SecurityProvider] WHERE ProviderClassName = @ProviderClassName;
    DELETE FROM [k2].[HostServer].[SecurityLabel] WHERE SecurityLabelName = @SecurityLabelName;
    INSERT INTO [k2].[HostServer].[SecurityProvider] VALUES (@AuthSecurityProviderID, @ProviderClassName);
    INSERT INTO [k2].[HostServer].[SecurityLabel] VALUES (@SecurityLabelID, @SecurityLabelName, @AuthSecurityProviderID, @AuthInit, @RoleSecurityProviderID, @RoleInit, @DefaultLabel);

    SELECT @SPProviderID = [SecurityProviderId] FROM [k2].[HostServer].[SecurityProvider] WHERE [ProviderClassName] = N'SourceCode.Security.Providers.SharePoint.SharePointProvider';
    IF NOT EXISTS (SELECT 1 FROM [k2].[HostServer].[GroupProvider] WHERE [SecurityLabelID] = @SecurityLabelID)
    BEGIN
    INSERT INTO [k2].[HostServer].[GroupProvider]
    (
    [GroupProviderID]
    ,[SecurityLabelID]
    ,[SecurityProviderID]
    ,[Name]
    ,[Init]
    )
    VALUES
    (
    NEWID()
    ,@SecurityLabelID
    ,@SPProviderID
    ,'*'
    ,'<init><label name="SP" /></init>'
    )
END
LDAP Setting Description
LdapConnection
  • LdapServer: This is the server or directory name (e.g. “denallix.com” or “mydns”).
  • LdapServerPort: This is the port for the connection. This can be 0 for the default (usually 389) or you can set a different one, such as for SSL (usually 636).
  • LdapAuthTypeConnect: This is the type of connection K2 makes whenever it queries the directory (such as for user information and group membership). “Negotiate” would be the simplest for AD, but if you need a username and password, use Basic instead. For more information see AuthType Enumeration (MSDN).
    This value should be set to Negotiate as it uses NTLM or Kerberos depending on the requirement.
  • LdapAuthTypeAuthenticateUser: This is the type of connection K2 makes whenever it authenticates a user when they enter their credentials. “Negotiate” is the simplest for AD, but if you need a username and password, use Basic instead. For more information see AuthType Enumeration (MSDN).
    This value should be set to Negotiate as it uses NTLM or Kerberos depending on the requirement.
  • LdapResolveAuthenticationUserToDistinguishedName: In some directories (such as Novell), users are logged in with their distinguished name instead of their username. If this is true, K2 takes the user’s name and queries the directory in order to retrieve the distinguished name. If users are logging in with their distinguished names (passing it in the K2 connection string), then this should be false as there’s no need to resolve it.
  • LdapAutoBind: Whether or not to avoid explicit binding in the connection (LDAP connects first and then binds to validate the connection). This is a compatibility setting and can usually be left false.
  • LdapScope: This is the scope of user searches. Unless you have specific requirements (such as only searching in a root OU), then “Subtree” is the recommended option. For more information see SearchScope Enumeration (MSDN).
  • LdapConnectIntegrated: Whether or not the connection has integrated authentication. If LdapAuthTypeConnect is “NTLM”, this would need to be true. This only correlates to K2’s own connections as end users do not make integrated connections.
  • LdapConnectUserName: If your LDAP directory doesn’t support integrated connections or you want to use an account different than the K2 service account, specify a user to query the directory. Some directories support connections with blank username/password for general queries, but you may find that you only receive a limited number of attributes.
  • LdapConnectUserPassword: The password for the LdapConnectUserName user.
  • LdapTimeout: A timeout for LDAP queries (in seconds). 0 means to use the default value of 120 seconds.
  • LdapProtocolVersion: The LDAP protocol version to use. 3 is recommended, but 2 typically works.
  • LdapSsl: Whether the connection uses SSL (ensure that the port used reflects this).
  • LdapServerCertificatePath: If you are using SSL, this is an optional value that allows you to verify the LDAP server’s SSL certificate (to ensure someone isn’t spoofing your user directory). This provides a local path (on the K2 server) to find the certificate. If no certificate is supplied and you’re doing SSL, then K2 assumes that you don’t want to check it and a non-SSL connection is made.
LdapUserSearchFormatString This is the LDAP query used to search for users. It should include a placeholder “{0}” for where to insert the user's ID. As this is in XML, escape any reserved XML characters (such as the ampersand character &). For example:
(&amp;(objectClass=Person)(objectCategory=User)(samAccountName={0})
LdapUserGroupSearchFormatString This is the LDAP query used to search for users that belong to a specific group. It should include a placeholder “{0}” for where to insert the group’s ID. Do not include wildcards as these get handled automatically. As this is in XML, escape any reserved XML characters (such as the ampersand character &). For example, to return users from this specific group and all nested groups:
(memberOf :1.2.840.113556.1.4.1941:={0})
For more information see Search Filter Syntax (MSDN).
LdapGroupSearchFormatString This is the LDAP query used to search for groups. It should include a placeholder “{0}” for where to insert the user’s ID. Do not include wildcards as these get handled automatically. As this is in XML, escape any reserved XML characters (such as the ampersand character &). For example:
(&amp;(objectCategory=Group)(samAccountName={0}))
LdapGroupMemberSearchFormatString This is the LDAP query used to search for groups of which the user is a member. It should include a placeholder “{0}” for where to insert the user’s ID. Do not include wildcards as these get handled automatically. As this is in XML, escape any reserved XML characters (such as the ampersand character &). For example, to return groups and all nested groups of which the user is a member:
(member:1.2.840.113556.1.4.1941:={0})
For more information see Search Filter Syntax (MSDN).
LdapUserBaseObject This is the LDAP base object from which all user searches are made. Make sure that this correlates correctly to your LdapScope setting above. . For example:
dc=denallix,dc=com
LdapGroupBaseObject This is the LDAP base object from which all group searches are made. Make sure that this correlates correctly to your LdapScope setting above. For example:
dc=denallix,dc=com
LdapUserAttributes The following is the set of attributes that are used in your directory. The available settings for each attribute are:
  • K2Name: This is the name that K2 knows the property by, for example, <K2LdapMapping K2Name="ID" LdapName="samAccountName" ObjectType="System.String" />. You should stick to the names supplied otherwise K2 will not know how to use the property. This name is case sensitive.
  • LDAPName: This is the name used in the LDAP directory (such as samAccountName). LDAP is generally case in-sensitive, however, make sure that, when setting these properties, your LDAP system does not see these as case-sensitive . If this value is blank, K2 takes the distinguished name of the object.
  • ObjectType: This setting tells K2 what it’s retrieving from this property. System.String (a string value) and System.Collections.ArrayList (a collection of values) are supported.
  • Multiline: Typically, properties are only found on the first line. However, some values (such as description) can be on multiple lines. Setting this property forces K2 to concatenate values.
  • FullOnly: Setting this to true means that is only retrieved as part of a full search. If the property take time to retrieve (such as group members, which all have to be resolved). If you find delays in searches, set this to true on as many properties as possible unless you find issues caused by missing properties.
  • SearchQuery: Some LDAP properties only include a distinguished name (such as memberOf). If you want to search for the user/group of that distinguished name, in order to replace this value with one K2 recognizes, you can supply a query here for K2 to use for the search. This is always a distinguished name and, because of that, there is no need for any placeholders. It should be a complete query.
  • SearchResultProperty: If you are using a SearchQuery, this specifies the property of the returned object you want to retrieve (such as samAccountName). This replaces the distinguished name originally retrieved for the attribute.
    The minimum set of required attributes for resolving users and groups is: ID, Name, DistinguishedName, and Description (where ID and Name are usually the same). Others may be used in K2 and therefore should be included where possible (such as e-mail and manager), but they are not required for base functionality.
    If you find that your queries are returning only a small number of attributes, it may mean that the user you'reconnecting with does not have sufficient privileges.
LdapGroupAttributes As above, except these attributes would be the ones returned for groups.

Register the LDAP User Manager

To register the LDAP User Manager, modify the SecurityLabels table in the database. This table stores the security label, security provider, and authorization/role initialization data for the user manager. The K2 User Manager sample scripts available for download allow you to add or remove a LDAP user manager. Make sure to edit the scripts to fit your configuration before executing them. Follow the steps below to add the LDAP user manager.

  1. Download and extract the K2 User Manager sample scripts.
  2. Open the K2 LDAP User Manager (Forms - Setup).sql script and edit it for your environment.
  3. Execute the K2 LDAP User Manager (Forms - Setup).sql script from Microsoft SQL Server Management Studio against the K2 database.
  4. You need to update of the existing user cache if you change user managers configuration. Execute this SQL command against the K2 database.
    Copy

    Update of the existing user cache

    UPDATE [K2].[Identity].[Identity]
        SET [ExpireOn] = GETDATE()
        ,[Resolved] = 0
        ,[ContainersResolved] = 0
        ,[ContainersExpireOn] = GETDATE()
        ,[MembersResolved] = 0
        ,[MembersExpireOn] = GETDATE()
    GO
                
  5. Restart the K2 Server service.
The example scripts contain references to the DLX SQL instance, the K2HostServer database and the Denallix.com domain. Edit the .sql files to replace these values before executing.

Create, Link and Map the Issuer to the Security Label

Read all the sets below before taking an actions
  1. Follow the user guide steps to set up a New Claim Mapping.

  2. Use the settings in the table below when setting your New Claim Mapping.

    Items Setting
    Security Lab K2FORMS
    Issuer K2 Forms STS
    Claim Type Info Checked
    Name Identity Issuer  
    User Token Identifier  
    Group Took Identifier  
    Identity Provider  
    Original Issuer FormsSTS
    Claim Type http://schemas.microsoft.com/identity/claims/idenityprovider
    Claim Value FormsSTS
    Identity  
    Original Issuer FormsSTS
    Claim Type http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name
    Claim Value  
    Security Label  
    Original Issuer FormsSTS
    Claim Type http://schemas.k2.com/identity/claims/securitylabelname
    Claim Value  

  3. Edit each Realm to add the K2 Forms STS to each Realm, the final result is shown below: