DNN Platform Multi-Factor Authentication Provider

More details about this project may be found on my blog.

Description

This authentication provider allows a host to configure enhanced authentication (including SMS, SMTP, YubiKey, and X.509 certificates) for various scenarios.

Goals

  • A robust, extensible multi-factor authentication framework for the DotNetNuke content management system.
  • Complete integration into the framework using existing extension points, with no core modifications or recompilation required.
  • Support for host-, administrator-, and user-level configuration, with the ability to vary required factors across an arbitrary set of roles.
  • A robust set of included factor providers, including SMS, secure SMTP, YubiKey (www.yubico.com), and X.509 certificate.
  • Extension points in the authentication system allowing for development of custom factors by third parties.
  • Reliance on the existing ASP.NET membership subsystem for existing (first-factor) authentication.
  • Minimization of "custom security" risk by relying, insofar as is possible, upon existing security infrastructure (ASP.NET membership, DotNetNuke portal security, password generation, et cetera.
  • As small an overall surface area as is possible, and an absolute reliance upon the existing ASP.NET membership system as a first-factor fallback, should any unforeseen vulnerability exist.

Background

The DotNetNuke content management system is a mature, robust, and widely-adopted web application framework. It offers role-based authentication and authorization using the ASP.NET membership subsystem, and allows for multiplexing across any number of websites per installation. Read more about DotNetNuke security-related functionality on their website.

However, DotNetNuke does not offer an out-of-the-box multi-factor authentication story. This is especially unfortunate, especially as the platform is more widely relied upon as a line-of-business portal for enterprise-scale applications such as high-volume e-commerce and banking. These applications, along with the fact that the platform offers cross-website "host" accounts, require a higher-than-normal level of authentication than a simple username/password combination is able to offer.

This project attempts to bridge that gap by extending existing DotNetNuke functionality to offer multi-factor authentication to those roles, users, and hosts configured to require it. Available factors include, in addition to the first-factor ASP.NET membership subsystem (which is always required), SMS, secure SMTP, and X.509 certificate-based authentication. The package is designed to be flexible and easily extended, allowing any arbitrary additional factors to be introduced by third-party developers.

Usage

This authentication extension has been designed for, tested against, and requires DotNetNuke version 5.0.1 or later. Details about core installation and the downloads therefor, are located on the DotNetNuke website.

Brief installation instructions

(see brandonhaynes.org for more detailed installation documentation, including screenshots)
  1. Download the latest release.
  2. Backup all data associated with your installation, including both files and database.
  3. Sign in as a host account.
  4. The default configuration is designed, for demonstration purposes, to enable a SMTP factor for host accounts. Ensure that your installation has specified valid SMTP settings and that your host account has been configured with an active e-mail account.
  5. Install the authentication extension via the Host->Extensions menu option.
  6. After installation, visit your site's login page (after logging out of your host account) to ensure the provider is functioning properly.
  7. Configure your web.config to select those factors and roles you wish to augment with additional security (see below).
  8. When satisfied with your ultimate configuration, disable the default DotNetNuke authentication system through the Host->Extensions->Default Authentication menu option.

Configuration

The DotNetNuke multi-factor authentication provider currently requires modification to the web.config file when specifying those roles that are to be authenticated with additional factors. This may be changed in the future and effectuated through the settings page.

The default addition to the installation's web.config file includes a node located at configuration/brandonHaynes. It is here that the factors -- and the roles that map thereto -- are defined:
<brandonHaynes>
  <authenticationFactors>
    <factor name="Membership" type="BrandonHaynes.Membership.Factors.MembershipFactor..." />
    <factor name="SMTP" text="Enter your one-time password:" 
        type="BrandonHaynes.Membership.Factors.SmtpFactor..." />
    <factor name="SMS" appId="3165534" userName="..." password="..." 
        text="Enter your one-time password:" 
        type="BrandonHaynes.Membership.Factors.SMSFactor..." />
    <factor name="X.509" text="A valid certificate is required to access this account." 
        type="BrandonHaynes.Membership.Factors.ClientCertificateFactor..." />
      <factor name="YubiKey" text="Activate your YubiKey now:" id="..." key="..." 
        type="BrandonHaynes.Membership.MultifactorMembershipProvider..." />
  </authenticationFactors>
  <authenticationMap>
    <role name="host">
      <factor name="YubiKey" />
    </role>
    <role name="Administrators">
      <factor name="SMS" />
    </role>
  </authenticationMap>
</brandonHaynes>

Here, we have five factors defined (ASP.NET membership, SMTP, SMS, YubiKey, and X.509 certificate) as children of the brandonHaynes/authenticationFactors node. Additional factors may be defined therein.

Under the brandonHaynes/authenticationMap node, we map roles to factors. In the example above, the host role requires a valid YubiKey one-time password and those in an administrator role requires a SMS-dispatched one-time-password. Additional roles and factors may be added (or removed) to enable virtually any configuration. Note that, regardless of configuration, the ASP.NET membership factor is always required.

Factors Included in this Distribution

The following factors are included in this distribution:
  • SMS. This factor utilizes the Clickatell SMS gateway for secure one-time password delivery. Factor configuration requires account id and password; this may be encrypted for additional protection (see this for details).
  • X.509. This factor utilizes the certificate presented by the client when making an authentication decision. The factor utilizes the built-in ASP.NET subsystem (which, itself, relies upon IIS) in making decisions related to the presence and validity of a client certificate. Assuming both, the certificate subject is compared to a (configurable) user property (by default the username). Alternate profile properties may be used as a basis for comparison by including a profileProperty attribute in the factor definition. For example, to compare a user's e-mail address, configure the factor as:
    <factor name="X.509" profileProperty="email" text="..."
         type="BrandonHaynes.Membership.Factors.ClientCertificateFactor..." />
  • SMTP. This factor utilizes the SMTP server configured for the current DotNetNuke website for transmission of one-time password. Though these settings may be configured to transmit this information securely, in most situations this configuration should not be relied upon for true out-of-band one-time-password transmission (an exception might exist for delivery to a SMS or handheld device external to the authenticating computer system).
  • YubiKey. This factor requires activation of a valid YubiKey (www.yubico.com) to authenticate. By default, the factor authenticates against https://api.yubico.com/wsapi/verify, but this may be changed by including a verifyUri attribute on the factor node. Note that by default if no YubiKey is associated with an authenticating account, it will be associated upon first use. Subsequent authentication requires the same YubiKey to be presented. This feature may be deactivated with an associateOnFirstUse="false" attribute. Note that if automatic association is disabled, accounts requiring YubiKey authentication must be manually associated (by a host). If possible, it is a good idea to disable automatic association after all accounts have associated for the first time.

Custom Factors

This authentication provider is designed to be highly extensible and to allow for additional factors to be added with relative ease. Developers may deploy their own factors by:
  • Including a constructor having the prototype of the form:
MyFactor(IDictionary<string, string> attributes);
  • Implementing the BrandonHaynes.Membership.IAuthenticationFactor interface, defined as:
public interface IAuthenticationFactor
	{
	string Name { get; }
	void Authenticate(UserInfo user, Credential credential);
	Control PromptControl { get; }
	}

Note that the PromptControl property is a control that handles the input of whatever additional credential (one-time-password or otherwise) is desired. Three are provided for use in custom development:
  1. MessagePrompt (to display a simple message),
  2. StringPrompt (to input a one-time-password), and
  3. NullPrompt (does not display or require any additional input).

Though any control may be used here, note that because of the way they are instantiated, much of the control life cycle is omitted (in particular ViewState and automatic IPostBackDataHandler handling is not activated). These controls must remain as simple as possible.

Custom SMS Gateways

The SMS factor is designed to be extendable and allow for integration with alternate SMS gateway providers. This may be effectuated by deriving from BrandonHaynes.Membership.SmsFactor and overriding one or more of the following methods:

// Override this method to send a specific one-time password to a telephone 
// number for a particular user using whatever custom SMS gateway is desired.
protected void SendSms(UserInfo user, string telephone, string onetimePassword);

// Override this method to format a given telephone number for transmission to a 
// custom SMS gateway service.  Note that the default implementation is 
// (unfortunately) US-centric and does not perform a robust E.164 formatting (code 
// submissions for this facet would be greatly appreciated!).  
string FormatTelephoneByCountry(UserInfo user, string telephone);

In Case of Emergency...

As with any authentication system, any failure that might occur has a high risk of locking a host out of his or her account. As such, I strongly recommend deploying this package to a staging server prior to production deployment, along with other reasonable precautions.

Should an unrecoverable lockout occur, please note that the default DotNetNuke authentication system may be re-enabled through modification to the dbo.Authentication table of your database. The following SQL will effectuate this (and at the same time disable all other authentication systems that might be available). Use it as an emergency escape.

UPDATE dbo.Authentication 
SET IsEnabled = 
	CASE WHEN AuthenticationType = 'DNN' THEN 1 ELSE 0 END

Note that you will need to recycle your application pool to realize this change; this may be most easily effectuated by recycling your IIS application pool, restarting IIS, or by making any change to your web.config file.

Feedback Appreciated!

Feedback about your experiences is needed, and greatly appreciated!

Last edited Apr 23 at 9:08 PM by BrandonHaynes, version 19