Optionally provide private feedback to help us improve this article...

Thank you for your feedback!


Creating Your Own UserIdentity Provider

The UserIdentity provider within InstantForum makes it easy to achieve a single sign on requirement with existing systems without having to modify core InstantForum code. This makes upgrading much easier as you won't need to modify the InstantForum code each time you upgrade.

In this example we'll create a basic UserIdentity provider to first check if user credentials exist within an external data source and if successful we'll persist user authentication via a regular in-memory ASP.NET session object. We would not suggest using session objects to persist user authentication however this will just help illustrate this example.

Creating a New Provider

Open Visual Studio and create a new C# class library project as shown below...

Next you'll need to reference the InstantASP.Common.dll and InstantASP.InstantForum.dll. Right click your project and select Add Reference as shown below. You will need to navigate to your InstantForum /Bin folder and select the InstantASP.Common.dll and InstantASP.InstantForum.dll.

Adding a reference to InstantASP.Common.dll and InstantASP.InstantForum.dll within your new project should pull in all other dependencies as shown below...

Let's Create Our Provider

Now we have the necessary reference we can start creating our own custom user identity provider for InstantForum. This identity provider will still use the InstantForum database to store and retrieve user information To demonstrate this provider we'll use ASP.NET session state to persist authentication. 

To get started within our new class we'll need to add a using reference...

using InstantASP.InstantForum.Providers.UserIdentity;

Then ensure our new class inherits from UserIdentityProvider as shown below...

Once our class inherits from UserIdentityProvider right click the UserIdentityProvider class name and select "Implement Abstract Class" to populate our new class with all methods we can implement within our provider. This is shown below...

Once you've implemented the abstract class your code should look like so...

We can now start populating the various methods provided by this provider to handle user storage & authentication within InstantForum. Below you can see a basic provider example that uses the InstantForum database to store user information but persists user authentication via a ASP.NET session object as opposed to a client side forms authentication cookie. 

using System;
using InstantASP.InstantForum.Providers.UserIdentity;

namespace MyCustomIdentityProvider
{
    public class Class1 : UserIdentityProvider
    {

        #region "Concrete Implementation"

        public override int InsertUpdateUser(InstantASP.InstantForum.Components.User user, string connString = "")
        {
            return InstantASP.InstantForum.Business.User.InsertUpdateUser(user, connString);
        }

        public override InstantASP.InstantForum.Components.User SelectUser(string identity, InstantASP.Common.Enumerations.EnumLoginUsing loginUsing)
        {
            InstantASP.InstantForum.Components.User user = (InstantASP.InstantForum.Components.User)InstantASP.Common.Cache.DataCache.Item(identity, InstantASP.InstantForum.Enumerations.EnumCachedIdentifiers.InstantForumUser.ToString());
            if (user == null)
            {
                user = new InstantASP.InstantForum.Components.User(identity);
                InstantASP.Common.Cache.DataCache.Add(identity, user, InstantASP.Common.Cache.Durations.Instance().InstantASP_User(), InstantASP.InstantForum.Enumerations.EnumCachedIdentifiers.InstantForumUser.ToString());
            }
            return user;
        }

        public override InstantASP.InstantForum.Components.User SelectUser(int UserID)
        {
            return new InstantASP.InstantForum.Components.User(UserID);
        }

        public override bool DeleteUser(int UserID)
        {
            InstantASP.InstantForum.Business.User.DeleteUser(UserID);
            return true;
        }

        public override int ValidateUser(
                 string username,
                 string password,
                 InstantASP.Common.Enumerations.EnumLoginUsing loginUsing)
        {

            // the ValidateUser method is called whenever a user attempts to login
            // Here you could add code to communicate 
            // with your own database to compare the 
            // users login credentials or perform other logic

            return InstantASP.Common.Business.UserRepository.ValidateUser(username, password, loginUsing);

        }

        public override InstantASP.InstantForum.Components.User 
            GetAuthenticatedUser(InstantASP.Common.Enumerations.EnumLoginUsing loginUsing = InstantASP.Common.Enumerations.EnumLoginUsing.EmailAddress, bool deleteAuthCookieIfUserNotFound = true)
        {

            // custom code for this example
            // this uses the session variable populated during the SignIn method
            // to obtain the current authenticated user 

            string sessionVariable = string.Empty;            
            if (System.Web.HttpContext.Current.Session["userId"] != null)            
                sessionVariable = System.Web.HttpContext.Current.Session["userId"].ToString();
            
            int userId;
            InstantASP.InstantForum.Components.User user = null;
            if (!string.IsNullOrEmpty(sessionVariable))
            {
                if (int.TryParse(sessionVariable, out userId))                
                    user  = SelectUser(userId);                
            }

            return user;
            
        }

        public override void SignIn(
            InstantASP.InstantForum.Components.User user,
            bool isPersistent = false,
            InstantASP.Common.Enumerations.EnumLoginUsing loginUsing = InstantASP.Common.Enumerations.EnumLoginUsing.EmailAddress)
        {

            // CUSTOM PROVIDER EXAMPLE CODE
            //  Here we use session state rather than a client side cookie to persist user authentication
            System.Web.HttpContext.Current.Session["userId"] = user.UserID.ToString();

        }

        public override void SignOut(bool deleteAllCookies = false)
        {       
            // clear current session state when users logs out
            if (System.Web.HttpContext.Current != null)
            {
                if (System.Web.HttpContext.Current.Session != null)
                    System.Web.HttpContext.Current.Session.Abandon();
            }
        }
        
        #endregion
        
        #region "Provider Implementation (No need to change)"

        public override string Description
        {
            get { throw new NotImplementedException(); }
        }

        public override void Initialize(string name, string desc, System.Collections.Specialized.NameValueCollection configValue)
        {
            throw new NotImplementedException();
        }

        public override string Name
        {
            get { throw new NotImplementedException(); }
        }

        #endregion

    }
}
 

Using The Custom Provider

Once you've created your new provider class library you can compile this into a .NET assembly. In this example our assembly is called MyCustomIdentityProvider.dll. We will need to copy the assembly containing our custom provider code into the InstantForum /bin folder. 

Once we copy the MyCustomIdentityProvider.dll into the InstantForum /Bin folder we can then register this assembly as an identity provider via the InstantForum web.config. You will need to locate the <providers> section within the InstantForum web.config and update as follows...

<providers>
<userIdentity defaultProvider="MyIdentityProvider">
<providers>
<add name="MyIdentityProvider" type="MyCustomIdentityProvider.Class1, MyCustomIdentityProvider"/>
<add name="InstantASPIdentityProvider" type="InstantASP.InstantForum.Providers.UserIdentity.InstantASPUserIdentityProvider, InstantASP.InstantForum"/>
<add name="OwinIdentityProvider" type="InstantASP.InstantForum.Providers.UserIdentity.OwinUserIdentityProvider, InstantASP.InstantForum"/>
</providers>
</userIdentity> ... ... other providers are registered below this line - removed for readability.

The "name" for your provider can be anything you choose. You will simply need to ensure the defaultProvider is set to your provider name as shown above. 

The "type" attribute above is separated like so type="namespace.classname, assemblyname".

That's It!

In this example we've learnt how to create a custom user identity provider for InstantForum. The process is virtually identical for our InstantKB provider as both use the same provider model. 

If we can assist further with any questions please don't hesitate to submit a support request