Introduction

K2 allows for multiple security providers to be used for authentication purposes. This allows a customer’s security provider to be modified when business requirements change, or to allow for multiple security providers for use with K2 Host Server.

Note: A security provider is where users and groups are stored, and where authentication is performed.

This document will walk you through how to register a security provider. Typically, the authentication mechanism is Active Directory (AD) or SQL. Both AD and SQL providers ship in the box with K2. However, custom security providers can be written for other sources (such as Oracle, LDAP).

Note: This document assumes some programming knowledge and familiarity with SQL Server.

How to Register a Security Provider

 
To register a new security provider, three tables in the K2 database must be modified:
  • AssemblyRegistration – Register the assembly so K2 can use it.
  • SecurityProvider – In order to register the security provider as a Type that implements IHostableSecurityProvider
  • SecurityLabel – This table maps the security provider to a label and stores initialization data
 
In this example, a single security provider is used for both authentication and user and group definition.
 

Code the Security Provider

 
In order to implement a new security provider, you will first have to code the authentication methods and role providers. Your code must implement the IHostableSecurityProvider interface.
Note: Please see the Download section for the Sample Security Provider attachment. In this sample, there are some comments in the methods that must be implemented for the provider. This is a sample for reference only.
For security reasons, the K2 server only loads custom assemblies that have been registered in the K2 database. This means that, at startup, if the K2 server is required to load a custom assembly, the custom assembly must be registered. Otherwise, only the out-of-the-box assemblies are loaded. 

This requirement applies to the assembly that implements the security interface, for example, IHostableSecurityProvider and excludes the assemblies that are referenced by the assembly implementing the interface. 

To illustrate: If assembly A implements IHostableSecurityProvider, and assembly A references assembly B, then you only need to register Assembly Ain the K2 database. You must copy Assembly A into the <install folder>\Host Server\bin\SecuirtyProviders and copy Assembly B, the referenced assembly, to <install folder>\Host Server\bin.

How to Register the Assembly

Use these steps to register the assembly.

  1. The assembly that contains your Security Provider, must be signed. Get the public key token for the assembly.
    To obtain the Public token key do the following
    • Open the Visual Studio command prompt
    • Type: sn.exe -T [full path to strongly named assembly]
  2. Run the following script against the Host Server database:
    INSERT INTO [HostServer].[AssemblyRegistration]
       ([AssemblyID]
       ,[AssemblyName]
       ,[PublicKeyToken]
       ,[Enabled])
    VALUES
       (newid()
       ,'[AssemblyName]'
       ,'[PublicKeyToken]'
       ,1)

    Where [AssemblyName] is the name of the assembly example: SourceCode.Security.Providers.SampleProvider (excluding the ‘.dll’, i.e. not the strong name) and where [PublicKeyToken] is the public key token that you signed the assembly with, obtained in step 1.

  3. Make the following change to the [K2 Install Dir]\Host Server\Bin\K2HostServer.exe.config file
    <appSettings>
    ...
    <add key="useassemblyregistration" value="true" />
    ...
    </appSettings>
  4. Restart the K2Server.
After developing and testing your security provider, compile your code. Copy the assembly into the following folder:

                <install folder>\Host Server\Bin\SecurityProviders
 
In order for the K2 server to register the new security provider, you must restart the K2 service.
 

Register the Security Provider in the Database

 
The next step is to insert the security provider information into the database. The following needs to be inserted into the HostServer database:
Note: The following code sample has place holders for the security provider information. They are marked with {}. Be sure to replace the place holder text with your security provider’s information.
 
INSERT INTO [HostServer].[SecurityProvider]
           ([SecurityProviderID]
           ,[ProviderClassName])
     VALUES
           (newid()
           ,'{Full Name of your Security Provider Class}')
 
 
 
INSERT INTO [HostServer].[SecurityLabel]
           ([SecurityLabelID]
           ,[SecurityLabelName]
           ,[AuthSecurityProviderID]
           ,[AuthInit]
           ,[RoleSecurityProviderID]
           ,[RoleInit]
           ,[DefaultLabel])
     VALUES
            ('6E5DEBDF-00A1-4fe8-9F6B-F0B732BCD1DC'
           ,'{LabelName}'
           ,'{GUID of SecurityProvider for Authentication Services(IAuthenticationProvider)}'
           ,'{Initialization data for the Authentication Provider instance}'
           ,'{GUID of the SecurityProvider for User and Group Listing services
             (IRoleProvider)
}'
           ,'{Initialization data for the User and Group listing provider}'
           ,1)


Important: Please note it is imperative that the [AuthInit] and [RoleInit] values in the [SecurityLabel] table are NOT NULL.
 

Resolving Users in the Context of Multiple Labels


When multiple security providers are used, multiple labels are registered with K2. This should be taken into account when creating a new security provider.
Note: The Label is a user-friendly representation of the Security Provider.
In the case of Active Directory, the label may differ from the actual domain name. Usually, one user manager is available per domain. When multiple domains have been configured, there may be scenarios where users may or may not exist in each domain. Therefore, extra care should be taken when testing to look for these special cases.
 
The K2 tag or identifier is a security label assigned to the User Manager instance. The UserManager instances must be labeled so that the users are uniquely identifiable.
Note: When no security tag or label is specified, the default domain label will be used.
Scenarios may exist as below, which resolves worklist items for BPUser. For this example, K2DEMO is the default domain:
 
  • BPUser – This user will resolve with the default label (K2), with the default domain (K2DEMO). The internal result used by K2 will be K2:K2DEMO\BPUser
  • K2DEMO\BPUser – This user will resolve with the default label (K2). The internal result used by K2 will be K2:K2DEMO\BPUser
  • K2:K2DEMO\BPUser – This is the fully qualified name with the label and domain specified. K2 will use this result as is.