OAuth Providers in Telligent Community

OAuth is an option to work along side Forms Authentication to enable users to log in with their Facebook or Twitter information.

Developers can extend OAuth support to other OAuth services or even add further functionality to the existing OAuth clients. The providers that come with Telligent Community collect only the information needed from a user to log them into the site. They do not support posting content back to Facebook or Twitter. However, a custom provider could be created to extend the default functionality.

Creating an OAuth client

All OAuth clients must implement the IOAuthClient interface and either IPlugin or IConfigurablePlugin as well. Here is a code sample that can be used as a base for creating custom clients, use it as a template for any custom OAuth clients.

using System;
using System.Web;
using Telligent.Common;
using Telligent.DynamicConfiguration.Components;
using Telligent.Evolution.Components;
using Telligent.Evolution.Extensibility.Authentication.Version1;
using Telligent.Evolution.Extensibility.Storage.Version1;
using Telligent.Evolution.Extensibility.Version1;

namespace My.OAuth
{
    public class MyOAuthClient : IOAuthClient, IConfigurablePlugin
    {
        private readonly IOAuthDataProvider _OAuthService;
		private readonly IPluginManager _pluginManager;
		private readonly IUserService _userService;

        public MyOAuthClient()
            : this(Services.Get<IUserService>(), 
			Services.Get<IOAuthDataProvider>(),
			Services.Get<IPluginManager>())
		{
		}

        public MyOAuthClient(IUserService userService, 
			IOAuthDataProvider oauthService, 
			IPluginManager pluginManager)
		{
			_OAuthService = oauthService;
			_pluginManager = pluginManager;
			_userService = userService;
		}

        #region IConfigurablePlugin

        public string Name { get { return "My OAuth Client"; } }
        public string Description { get { return "Enables users to authenticate using their XYZ account."; } }

        public void Initialize() { }

        protected IPluginConfiguration Configuration
        {
            get;
            private set;
        }

        #endregion

        public bool Enabled
        {
            // If more values need to be validated, add the validation here.
            get { return _pluginManager.IsEnabled(this); }
        }

        // Must be a unique oauth type
        public string ClientType { get { return "myoauth"; } }

        // Stores key and password for OAuth application
        public virtual string ConsumerKey { get { return Configuration.GetString("ConsumerKey"); } }
        public virtual string ConsumerSecret { get { return Configuration.GetString("ConsumerSecret"); } }
        public virtual string AuthorizeBaseUrl { get { return Configuration.GetString("AuthorizeBaseUrl"); } }
        public virtual string AccessTokenUrl { get { return Configuration.GetString("AccessTokenUrl"); } }
        public virtual string FileStoreKey { get { return "oauthimages"; } }

        private string _callbackUrl;
        public virtual string CallbackUrl
        {
            get
            {
                return _callbackUrl;
            }
            set
            {
                // Enforces https when making the callback.
                // Remove if this is not required for your client.
                if (!string.IsNullOrEmpty(value) && value.StartsWith("http:"))
                    _callbackUrl = "https" + value.Substring(4);
                else
                    _callbackUrl = value;
            }
        }

        // This returns the url to an image representing your OAuth provider.
        // The image is shown when selecting what client to use when logging in and
        //  next to the user's avatar when logged in.
        public string IconUrl
        {
            get
            {
                try
                {
                    ICentralizedFile file = CentralizedFileStorage.GetFileStore(FileStoreKey).GetFile(string.Empty, "myoauth.png");
                    if (file != null)
                        return CentralizedFileStorage.GetGenericDownloadUrl(file);
                    return null;
                }
                catch
                {
                    return null;
                }
            }
        }

        // Return the a color in hex format representing your OAuth client.
        public string ThemeColor
        {
            get { return "0000FF"; }
        }

        // This is the name shown to users for your OAuth client
        public string ClientName
        {
            get { return "My OAuth"; }
        }

        // Your privacy statement should include what privacy information
        //  is being collected about the user using this OAuth client.
        public string Privacy
        {
            get { return "Privacy statement"; }
        }

        // This is html that will be executed when a client logs out
        //  after being logged in through this OAuth client.
        //  Use this to perform further actions if needed.
        public string ClientLogoutScript
        {
            get { return ""; }
        }

        // Returns the Url to the OAuth service that will
        //  authorize the user and return back to Telligent Evolution.
        public string GetAuthorizationLink()
        {
            return "";
        }

        // This method is called when the user is redirected to
        //  Telligent Evolution after logging in through the OAuth service.
        // The method must return an OAuthData object based on the user's
        //  information provided by the service or return null.
        public OAuthData ProcessLogin(HttpContextBase context)
        {
            // Get access token
            string UID = ""; // Change this to retrieve the actual UID
            OAuthLink link = _OAuthService.GetOAuthLink(ClientType, UID);
            OAuthData data = new OAuthData {ClientType = this.ClientType, ClientId = UID};

            User user = null;
            if (link != null)
                user = _userService.GetUser(link.UserId);

            if (link != null && user != null)
            {
                // User has logged in before
                data.UserName = user.Username;
                data.Email = user.Email;
                data.CommonName = user.DisplayName;
                data.AvatarUrl = user.AvatarUrl;
            }
            else
            {
                // The user hasn't used this OAuth client to log in before
                // Add populate the OAuthData object with as much of the data
                //  as can be collected.  Whatever isn't collected will be
                //  gathered from the client directly.
            }
        }

        public void Update(IPluginConfiguration configuration)
        {
            Configuration = configuration;
        }

        // The configuration options are defined here. The values provided here
        //  are for convenience and not necessarily the values your OAuth client will
        //  require to be configured.  These may be changed as needed.
        public PropertyGroup[] ConfigurationOptions
        {
            get
            {
                PropertyGroup[] groups = new[] { new PropertyGroup("options", "Options", 0) };

                var consumerKey = new Property("ConsumerKey", "Consumer Key", PropertyType.String, 0, "");
                consumerKey.Rules.Add(new PropertyRule(typeof(Telligent.Evolution.Controls.PropertyRules.TrimStringRule), false));
                groups[0].Properties.Add(consumerKey);

                var consumerSecret = new Property("ConsumerSecret", "Consumer Secret", PropertyType.String, 0, "");
                consumerSecret.Rules.Add(new PropertyRule(typeof(Telligent.Evolution.Controls.PropertyRules.TrimStringRule), false));
                groups[0].Properties.Add(consumerSecret);

                groups[0].Properties.Add(new Property("AuthorizeBaseUrl", "Authorize Base URL", PropertyType.String, 0, "https://path/to/user/authorization"));
                groups[0].Properties.Add(new Property("AccessTokenUrl", "Access Token URL", PropertyType.String, 0, "https://path/to/retrieve/access/token"));

                return groups;
            }
        }
    }
}

Once the client is enabled in the plugins list, users will be able to use the custom OAuth client via the log in page.

Best practices

  • When accessing a user's private information, it is best to use https instead of http to ensure the user's information is retrieved securely.
  • Using configuration options to set the ConsumerKey and ConsumerSecret is preferred to hard coding the values so that if the values change, the OAuth client does not have to be recompiled.

Related