The ININ.IceLib.Connection namespace contains classes for connecting to an Interaction Center server. The Session class is used to establish a connection using IceLib. Nearly every operation performed with IceLib is done relative to the Session class instance that was initially used to connect to the server.

When establishing the IceLib session, several "settings" classes must be provided, including one for authentication (a class derived from AuthSettings), one for which Interaction Center to connect to (HostSettings), one containing some general session behavior (SessionSettings), and one for station settings (a class derived from StationSettings).

Jump to a code example:

Establishing a Basic Connection

The following example illustrates how to establish a basic connection.

Note

This example's use of the basic Interaction Center or Windows authentication type requires the Logon Authentication Configuration dialog in Interaction Administrator to have the appropriate Allow Windows authentication or Allow IC authentication setting enabled. See the Authentication concept page for more information.

CopyC#
// The IceLib Session can be created once and used for the life of the process.
Session session = new Session();
// An event handler is usually added to monitor connection state changes.
session.ConnectionStateChanged += delegate { /* React to connection state changes. */ };

// The application name can be displayed in Interaction Supervisor and is used for diagnostic operations.
SessionSettings sessionSettings = new SessionSettings();
sessionSettings.ApplicationName = "<Custom Application Name>";

// Specify the server being connected to (which is usually the IC server name).
// (It can also be a DNS "A" record that refers to both IC servers in a switchover pair.)
HostEndpoint hostEndpoint = new HostEndpoint("<IC Server Name>");
HostSettings hostSettings = new HostSettings(hostEndpoint);

// There are many options for specifying user authentication information.
// (See the derived classes of ININ.IceLib.Connection.AuthSettings for more information.)
// 
// The current windows user's windows authentication can be used (if the IC user is configured with NT credentials).
WindowsAuthSettings authSettings = new WindowsAuthSettings();
// Alternatively, IC authentication can be used.
ICAuthSettings icAuthSettings = new ICAuthSettings("<IC_User_LoginID>", "<IC_User_Password>");

// There are many options for specifying IC station information.
// (See the derived classes of ININ.IceLib.Connection.StationSettings for more information.)
// 
// If the application does not require a Station login, a simple "stationless" connection can be used.
StationlessSettings stationSettings = new StationlessSettings();
// Alternatively, an IC station could be specified.
WorkstationSettings workstationSettings = new WorkstationSettings("<IC_StationID>", SupportedMedia.Call);
// Or, a dynamic remote number station could be specified.
RemoteNumberSettings remoteNumberSettings = new RemoteNumberSettings(SupportedMedia.Call, "555-555-5555", true);

// Note: Consider using the ConnectAsync method to avoid blocking the thread.
session.Connect(sessionSettings, hostSettings, authSettings, stationSettings);

Back to Introduction

Establishing a Connection with Single Sign-On

The following example illustrates how to establish a Single Sign-On connection.

Note

This example's use of the Security Token Service authentication type requires an Identity Provider to be configured in Interaction Administrator. See the Authentication concept page for more information.

CopyC#
public void EstablishSsoConnection()
{
    // For this example, the focus is on the authSettings part of the connection process, so we'll skip over the following parts.
    // See other examples for details on these settings classes.
    Session session = new Session();
    SessionSettings sessionSettings;
    HostSettings hostSettings;
    StationSettings stationSettings;
    CreateExampleSettings(out sessionSettings, out hostSettings, out stationSettings);

    // Optionally, the SSO user ID and password can be explicitly specified.
    // This GetSsoCredentials method is representative of custom application code that would obtain those values.
    string ssoUserName;
    SecureString ssoPassword;
    GetSsoCredentials(out ssoUserName, out ssoPassword);

    // SSO authentication provider(s) are configured in Interaction Administrator.
    // Then, one must be selected either programmatically or by prompting the user.
    string isoLanguage = "en-US";
    AllowableAuthentications allowableAuthentications = Session.GetAllowableAuthentications(hostSettings, isoLanguage);
    // This PromptForSelectedProvider method is representative of custom application code that would prompt for the selected provider.
    AuthProviderDefinition providerDefinition = PromptForSelectedProvider(allowableAuthentications.AuthProviderDefinitions);

    SecurityTokenServiceAuthParameters stsParams = new SecurityTokenServiceAuthParameters();
    // Optionally, the PresenterFactory allows for custom prompting of SSO credentials.
    stsParams.PresenterFactory = PresenterFactory;
    // Optionally, the SSO user ID and password can be explicitly specified.
    stsParams.UserName = ssoUserName;
    stsParams.Password = ssoPassword;
    // IceLib will automatically use persisted STS tokens, for single sign-on behavior, if these properties are set to true.
    // They default to false, requiring explicit opt-in.
    stsParams.UsePersistedToken = true;
    stsParams.PersistToken = true;

    // The SSO authSettings class is constructed from the selected AuthProviderDefinition and the STS parameters.
    SecurityTokenServiceAuthSettings authSettings = new SecurityTokenServiceAuthSettings(providerDefinition.ProviderContext, stsParams);

    // Note: Consider using the ConnectAsync method to avoid blocking the thread.
    session.Connect(sessionSettings, hostSettings, authSettings, stationSettings);
}

internal class MySecurityTokenServicePresenter : SecurityTokenServicePresenter
{
    private readonly Control _ParentControlForInvoke;

    public MySecurityTokenServicePresenter(SecurityTokenServicePresenterContext securityTokenServicePresenterContext, Control parentControlForInvoke)
        : base(securityTokenServicePresenterContext)
    {
        _ParentControlForInvoke = parentControlForInvoke;
    }

    protected override void HandleTryPromptForBrowserCredentials(SingleSignOnRequestData singleSignOnRequestData)
    {
        // This method can be overridden in order to show a browser dialog to use an external Identity Provider.

        // In order to ensure the proper flow of events for Single Sign On, when using a 3rd 
        // party Identity Provider within a browser window, the operation must be performed 
        // synchronously.  If performed asynchronously, the Single Sign On flow will move forward 
        // without receiving the proper credentials, and authentication will fail.
        _ParentControlForInvoke.Invoke(
            new MethodInvoker(() =>
            {
                // This dialog would need to be created by the custom application.
                // This dialog will need to have some form of WebBrowser control that can
                // utilize the SriptableObject from the singleSignOnRequestData.
                var browserDialog = new BrowserDialog();

                singleSignOnRequestData.ScriptableObject.RequestBrowserClose += (s, args) => browserDialog.Close();
                browserDialog.SetSingleSignOnRequestData(singleSignOnRequestData);
                browserDialog.ShowDialog(_ParentControlForInvoke);
            }));
    }

    protected override bool HandleTryPromptForCredentials(out string userName, out SecureString password)
    {
        // This method can be overridden in order to prompt the user for their SSO credentials.
        string promptedSsoUserName = "<prompted SSO user ID>";
        string promptedSsoPassword = "<prompted SSO password>";

        userName = promptedSsoUserName;
        password = new SecureString();
        foreach (char c in promptedSsoPassword)
        {
            password.AppendChar(c);
        }
        return true;
    }
}

internal SecurityTokenServicePresenter PresenterFactory(SecurityTokenServicePresenterContext securityTokenServicePresenterContext)
{
    // Simple factory to create the SecurityTokenServicePresenter class
    return new MySecurityTokenServicePresenter(securityTokenServicePresenterContext, _ParentControlForInvoke);
}

The following example illustrates the basic code necessary for the Web Browser Dialog.

CopyC#
public partial class BrowserDialog : Form
{
    public BrowserDialog()
    {
        InitializeComponent();
    }

    internal void SetSingleSignOnRequestData(SingleSignOnRequestData singleSignOnRequestData)
    {
        _WebBrowser.ObjectForScripting = singleSignOnRequestData.ScriptableObject;
        _WebBrowser.Navigate(singleSignOnRequestData.SingleSignOnUri);
    }
}

Back to Introduction

Creating a Session on Behalf of Another User

The following example shows how to monitor for sessions created by other users and then how to create a proxy connection to the IC server for another user, based on the authentication credentials of a special "elevated rights" user.

Note

This example's use of the Windows authentication type requires an Identity Provider to be configured in Interaction Administrator. See the Authentication concept page for more information.

CopyC#
private void StartSessionWatch()
{
    // For this example, the focus is on watching for sessions created by a particular target User, then creating a proxy connection as
    // if we were that target User, but authenticated using a special "elevated rights" user's credentials.  This is a model used by some
    // server-side integrations, where the server-side component connects as the single "elevated rights" user and can then perform
    // operations on behalf of other users in the system.

    // We'll skip over creation of this server-side application's Session.
    // See other examples for basic details on establishing a connection with the server.
    Session session = CreateSessionForElevatedRightsUser();

    // For this example, we create a "session watch" to monitor for other applications/users that are connecting to the server.
    // Alternatively, a "proxy login" could be create for a user that was obtained based on some other application logic.
    SessionWatch sessionWatch = new SessionWatch(session);

    // Register the event handlers for watched session changes.
    sessionWatch.SessionWatchedUserAdded += SessionWatchedUserAdded;
    sessionWatch.SessionWatchedUserRemoved += SessionWatchedUserRemoved;

    // A session watch can watch for sessions for a given IC User, for an IC Station, or for a Machine.
    // For this example, we'll assume that a particular IC User is to be watched, based on external application needs.
    string targetIcUserId = "<target user ID>";

    SessionWatchId[] sessionsToWatch = new SessionWatchId[]
    {
        new SessionWatchId(SessionWatchType.User, targetIcUserId)
    };

    // Start monitoring for watched session changes for the specified criteria.
    ReadOnlyCollection<SessionWatchSettings> watchSettings = sessionWatch.StartWatching(sessionsToWatch);

    // The result contains any existing connected sessions that match the session watch criteria.
    // The SessionWatchedUser* events will be invoked as matching sessions are connected/disconnected.
    foreach (SessionWatchSettings setting in watchSettings)
    {
        // For this example, we plan on creating a proxy connection on behalf of the target user.
        EstablishProxyConnectionToSession(setting.UserName,
                                          setting.SessionSettings,
                                          session.GetHostSettings(),
                                          setting.StationSettings);
    }
}

private void EstablishProxyConnectionToSession(string targetUserId,
                                               SessionSettings sessionSettings,
                                               HostSettings hostSettings,
                                               StationSettings stationSettings)
{
    // Here we assume that the current windows account under which this application is running is the one associated with
    // the elevated rights user.
    // 
    // Note that the IC user that is used to "vouch for" targetUserId's login must have "elevated rights" that allow it to serve
    // as a proxy for the authentication of other Interaction Center users.  The "elevated rights" user should be created
    // specifically for the server-side application's use, with very few rights other than the ability to proxy authentication.
    // 
    // The "elevated rights" user must have a specific "Proxy Logins" Access Control right configured on their Interaction Center
    // User via the Interaction Administrator application. This setting is in the "Miscellaneous" section of the Access Control
    // settings.
    ProxyWindowsAuthSettings proxyAuthSettings = new ProxyWindowsAuthSettings(targetUserId, ProxyTargetUserType.ICUser);

    // Alternatively, explicit IC user credentials (i.e. user ID and password) can be specified, but then often those credentials
    // are persisted somewhere to configure the custom application, so this is usually less secure than using Windows-based
    // authentication.
    // string elevatedRightsIcUserId = "<elevated rights user ID>";
    // string elevatedRightsIcPassword = "<elevated rights user password>";
    // ProxyAuthSettings proxyAuthSettings = new ProxyAuthSettings(elevatedRightsIcUserId, elevatedRightsIcPassword, userName);

    // Next, we create a new, separate, Session for the connection of the proxy login.
    // This Session will have the "context" (e.g. rights) of the target User's account, not of the elevated rights user's account.
    // 
    // What makes this a "proxy login" is that either ProxyWindowsAuthSettings or ProxyAuthSettings is used as the authSettings parameter.
    Session proxySession = new Session();

    // For this example, we intend to make calls on behalf of the user, using their station.
    // So, we re-use the same station that was part of the session watch result for the user being proxied.
    proxySession.Connect(sessionSettings, hostSettings, proxyAuthSettings, stationSettings);
}

Back to Introduction