{"id":50,"date":"2009-05-01T08:05:08","date_gmt":"2009-05-01T12:05:08","guid":{"rendered":"http:\/\/blogs.law.harvard.edu\/brandonhaynes\/?p=50"},"modified":"2009-05-02T08:05:33","modified_gmt":"2009-05-02T12:05:33","slug":"dotnetnuke-multi-factor-authentication-provider","status":"publish","type":"post","link":"https:\/\/archive.blogs.harvard.edu\/brandonhaynes\/2009\/05\/01\/dotnetnuke-multi-factor-authentication-provider\/","title":{"rendered":"DotNetNuke Multi-Factor Authentication Provider"},"content":{"rendered":"<div style=\"float: right\">\n<div id=\"attachment_49\" style=\"width: 160px\" class=\"wp-caption alignright\"> <a href=\"http:\/\/blogs.law.harvard.edu\/brandonhaynes\/files\/2009\/04\/multifactoronetimeandcertificate.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-49\" class=\"size-thumbnail wp-image-49\" src=\"http:\/\/blogs.law.harvard.edu\/brandonhaynes\/files\/2009\/04\/multifactoronetime-150x150.png\" alt=\"DotNetNuke Multifactor Authentication Requiring Password, One-Time SMS PIN, and X.509 Certificate\" width=\"150\" height=\"150\" \/><\/a><p id=\"caption-attachment-49\" class=\"wp-caption-text\">DotNetNuke Multifactor Authentication Requiring Password, One-Time SMS PIN, and X.509 Certificate<\/p><\/div>\n<\/div>\n<p>I am pleased to announce an initial release of a multi-factor provider for the DotNetNuke content management system.<\/p>\n<p>This authentication provider allows a host to configure enhanced authentication (including SMS, SMTP, YubiKey, and X.509 certificates) for any number and combination of portal roles. Each factor must be fulfilled prior to authentication being granted, increasing overall security.<\/p>\n<p>This package may be downloaded from it&#8217;s project site, located at <a href=\"http:\/\/dnnmultifactor.codeplex.com\">http:\/\/dnnmultifactor.codeplex.com<\/a>.<\/p>\n<h2>Goals<\/h2>\n<ul>\n<li>A robust, extensible multi-factor authentication framework for the DotNetNuke content management system.<\/li>\n<li>Complete integration into the framework using existing extension points, with no core modifications or recompilation required.<\/li>\n<li>Support for host-, administrator-, and user-level configuration, with the ability to vary required factors across an arbitrary set of roles.<\/li>\n<li>A robust set of included factor providers, including SMS, secure SMTP, YubiKey (<a class=\"externalLink\" href=\"http:\/\/www.yubico.com\/\">www.yubico.com<\/a>), and X.509 certificate.<\/li>\n<li>Extension points in the authentication system allowing for development of custom factors by third parties.<\/li>\n<li>Reliance on the existing ASP.NET membership subsystem for existing (first-factor) authentication.<\/li>\n<li>Minimization of &#8220;custom security&#8221; risk by relying, insofar as is possible, upon existing security infrastructure (ASP.NET membership, DotNetNuke portal security, password generation, et cetera.<\/li>\n<li>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.<\/li>\n<\/ul>\n<h2><!--more--><\/h2>\n<h2>Background<\/h2>\n<p>The <a class=\"externalLink\" href=\"http:\/\/www.dotnetnuke.com\/\">DotNetNuke content management system<\/a> is a mature, robust, and widely-adopted web application framework. It offers role-based authentication and authorization using the <a class=\"externalLink\" href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/yh26yfzy.aspx\">ASP.NET membership subsystem<\/a>, and allows for multiplexing across any number of websites per installation. Read more about DotNetNuke security-related functionality <a class=\"externalLink\" href=\"http:\/\/www.dotnetnuke.com\/Products\/DotNetNuke\/Security\/tabid\/1230\/Default.aspx\">on their website<\/a>.<\/p>\n<div style=\"float:right\">\n<div id=\"attachment_49\" style=\"width: 160px\" class=\"wp-caption alignright\"><a href=\"http:\/\/blogs.law.harvard.edu\/brandonhaynes\/files\/2009\/04\/multifactoronetime.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-49\" class=\"size-thumbnail wp-image-49\" src=\"http:\/\/blogs.law.harvard.edu\/brandonhaynes\/files\/2009\/04\/multifactoronetime-150x150.png\" alt=\"DotNetNuke Multifactor Authentication Requiring Password and One-Time SMS PIN\" width=\"150\" height=\"150\" \/><\/a><p id=\"caption-attachment-49\" class=\"wp-caption-text\">DotNetNuke Multifactor Authentication Requiring Password and One-Time SMS PIN<\/p><\/div>\n<\/div>\n<p>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 &#8220;host&#8221; accounts, require a higher-than-normal level of authentication than a simple username\/password combination is able to offer.<\/p>\n<p>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.<\/p>\n<h2>Usage<\/h2>\n<p>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 <a class=\"externalLink\" href=\"http:\/\/www.dotnetnuke.com\/tabid\/125\/default.aspx\">on the DotNetNuke website<\/a>.<\/p>\n<h4>Installation instructions<\/h4>\n<ol>\n<li>Download the <a class=\"externalLink\" href=\"http:\/\/dnnmultifactor.codeplex.com\/Release\/ProjectReleases.aspx\">latest release<\/a>.<\/li>\n<li><a href=\"http:\/\/www.mitchelsellers.com\/Blogs\/tabid\/54\/articleType\/ArticleView\/articleId\/33\/Default.aspx\" target=\"_blank\">Backup all data<\/a> associated with your installation, including both files and database.<\/li>\n<li>Sign in as a host account.<\/li>\n<li>The default configuration is designed, for demonstration purposes, to enable a SMTP factor for host accounts. Ensure that your installation has specified <a href=\"http:\/\/www.mitchelsellers.com\/blogs\/articletype\/articleview\/articleid\/189\/dotnetnuke-host-settings-explained.aspx\">valid SMTP settings<\/a> and that your host account has been configured with an active e-mail account.<\/li>\n<li>Install the authentication extension via the Host-&gt;Extensions menu option.<\/li>\n<li>After installation, visit your site&#8217;s login page (after logging out of your host account) to ensure the provider is functioning properly.<\/li>\n<li>Configure your web.config to select those factors and roles you wish to augment with additional security (see below).<\/li>\n<li>When satisfied with your ultimate configuration, disable the default DotNetNuke authentication system through the Host-&gt;Extensions-&gt;Default Authentication menu option.<\/li>\n<\/ol>\n<h2>Configuration<\/h2>\n<p>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.<\/p>\n<p>The default addition to the installation&#8217;s web.config file includes a node located at <span class=\"codeInline\">configuration\/brandonHaynes<\/span>. It is here that the factors &#8212; and the roles that map thereto &#8212; are defined:<\/p>\n<div>\n<pre><span>&lt;<\/span><span>brandonHaynes<\/span><span>&gt;<\/span>\r\n  <span>&lt;<\/span><span>authenticationFactors<\/span><span>&gt;<\/span>\r\n    <span>&lt;<\/span><span>factor<\/span> <span>name<\/span><span>=<\/span><span>\"<\/span><span>Membership<\/span><span>\"<\/span> <span>type<\/span><span>=<\/span><span>\"<\/span><span>BrandonHaynes.Membership.Factors.MembershipFactor...<\/span><span>\"<\/span> <span>\/&gt;<\/span>\r\n    <span>&lt;<\/span><span>factor<\/span> <span>name<\/span><span>=<\/span><span>\"<\/span><span>SMTP<\/span><span>\"<\/span> <span>text<\/span><span>=<\/span><span>\"<\/span><span>Enter your one-time password:<\/span><span>\"<\/span>\r\n        <span>type<\/span><span>=<\/span><span>\"<\/span><span>BrandonHaynes.Membership.Factors.SmtpFactor...<\/span><span>\"<\/span> <span>\/&gt;<\/span>\r\n    <span>&lt;<\/span><span>factor<\/span> <span>name<\/span><span>=<\/span><span>\"<\/span><span>SMS<\/span><span>\"<\/span> <span>appId<\/span><span>=<\/span><span>\"<\/span><span>3165534<\/span><span>\"<\/span> <span>userName<\/span><span>=<\/span><span>\"<\/span><span>...<\/span><span>\"<\/span> <span>password<\/span><span>=<\/span><span>\"<\/span><span>...<\/span><span>\"<\/span>\r\n        <span>text<\/span><span>=<\/span><span>\"<\/span><span>Enter your one-time password:<\/span><span>\"<\/span>\r\n        <span>type<\/span><span>=<\/span><span>\"<\/span><span>BrandonHaynes.Membership.Factors.SMSFactor...<\/span><span>\"<\/span> <span>\/&gt;<\/span>\r\n    <span>&lt;<\/span><span>factor<\/span> <span>name<\/span><span>=<\/span><span>\"<\/span><span>X.509<\/span><span>\"<\/span> <span>text<\/span><span>=<\/span><span>\"<\/span><span>A valid certificate is required to access this account.<\/span><span>\"<\/span>\r\n        <span>type<\/span><span>=<\/span><span>\"<\/span><span>BrandonHaynes.Membership.Factors.ClientCertificateFactor...<\/span><span>\"<\/span> <span>\/&gt;<\/span>\r\n      <span>&lt;<\/span><span>factor<\/span> <span>name<\/span><span>=<\/span><span>\"<\/span><span>YubiKey<\/span><span>\"<\/span> <span>text<\/span><span>=<\/span><span>\"<\/span><span>Activate your YubiKey now:<\/span><span>\"<\/span> <span>id<\/span><span>=<\/span><span>\"<\/span><span>...<\/span><span>\"<\/span> <span>key<\/span><span>=<\/span><span>\"<\/span><span>...<\/span><span>\"<\/span>\r\n        <span>type<\/span><span>=<\/span><span>\"<\/span><span>BrandonHaynes.Membership.MultifactorMembershipProvider...<\/span><span>\"<\/span> <span>\/&gt;<\/span>\r\n  <span>&lt;\/<\/span><span>authenticationFactors<\/span><span>&gt;<\/span>\r\n  <span>&lt;<\/span><span>authenticationMap<\/span><span>&gt;<\/span>\r\n    <span>&lt;<\/span><span>role<\/span> <span>name<\/span><span>=<\/span><span>\"<\/span><span>host<\/span><span>\"<\/span><span>&gt;<\/span>\r\n      <span>&lt;<\/span><span>factor<\/span> <span>name<\/span><span>=<\/span><span>\"<\/span><span>YubiKey<\/span><span>\"<\/span> <span>\/&gt;<\/span>\r\n    <span>&lt;\/<\/span><span>role<\/span><span>&gt;<\/span>\r\n    <span>&lt;<\/span><span>role<\/span> <span>name<\/span><span>=<\/span><span>\"<\/span><span>Administrators<\/span><span>\"<\/span><span>&gt;<\/span>\r\n      <span>&lt;<\/span><span>factor<\/span> <span>name<\/span><span>=<\/span><span>\"<\/span><span>SMS<\/span><span>\"<\/span> <span>\/&gt;<\/span>\r\n    <span>&lt;\/<\/span><span>role<\/span><span>&gt;<\/span>\r\n  <span>&lt;\/<\/span><span>authenticationMap<\/span><span>&gt;<\/span>\r\n<span>&lt;\/<\/span><span>brandonHaynes<\/span><span>&gt;<\/span><\/pre>\n<\/div>\n<p>Here, we have five factors defined (ASP.NET membership, SMTP, SMS, YubiKey, and X.509 certificate) as children of the <span class=\"codeInline\">brandonHaynes\/authenticationFactors<\/span> node. Additional factors may be defined therein.<\/p>\n<p>Under the <span class=\"codeInline\">brandonHaynes\/authenticationMap<\/span> 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 <strong>always<\/strong> required.<\/p>\n<h2>Factors Included in this Distribution<\/h2>\n<p>The following factors are included in this distribution:<\/p>\n<ul>\n<li>SMS. This factor utilizes the <a class=\"externalLink\" href=\"http:\/\/clickatell.com\/\">Clickatell<\/a> SMS gateway for secure one-time password delivery. Factor configuration requires account id and password; this may be encrypted for additional protection (see <a class=\"externalLink\" href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/dtkwfdky.aspx\">this<\/a> for details).<\/li>\n<li>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 <span class=\"codeInline\">profileProperty<\/span> attribute in the factor definition. For example, to compare a user&#8217;s e-mail address, configure the factor as:<\/li>\n<\/ul>\n<div>\n<pre>    <span>&lt;<\/span><span>factor<\/span> <span>name<\/span><span>=<\/span><span>\"<\/span><span>X.509<\/span><span>\"<\/span> <span>profileProperty<\/span><span>=<\/span><span>\"<\/span><span>email<\/span><span>\"<\/span> <span>text<\/span><span>=<\/span><span>\"<\/span><span>...<\/span><span>\"<\/span>\r\n         <span>type<\/span><span>=<\/span><span>\"<\/span><span>BrandonHaynes.Membership.Factors.ClientCertificateFactor...<\/span><span>\"<\/span> <span>\/&gt;<\/span><\/pre>\n<\/div>\n<ul>\n<li>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).<\/li>\n<li>YubiKey. This factor requires activation of a valid YubiKey (<a class=\"externalLink\" href=\"http:\/\/www.yubico.com\/\">www.yubico.com<\/a>) to authenticate. By default, the factor authenticates against<a class=\"externalLink\" href=\"https:\/\/api.yubico.com\/wsapi\/verify\">https:\/\/api.yubico.com\/wsapi\/verify<\/a>, 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=&#8221;false&#8221; 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.<\/li>\n<\/ul>\n<h2>Custom Factors<\/h2>\n<p>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:<\/p>\n<ul>\n<li>Including a constructor having the prototype of the form:<\/li>\n<\/ul>\n<div>\n<pre style=\"padding-left: 60px\">MyFactor(IDictionary&lt;<span>string<\/span>, <span>string<\/span>&gt; attributes);<\/pre>\n<\/div>\n<ul>\n<li>Implementing the BrandonHaynes.Membership.IAuthenticationFactor interface, defined as:<\/li>\n<\/ul>\n<div>\n<pre style=\"padding-left: 60px\"><span>public<\/span> <span>interface<\/span><span> IAuthenticationFactor\r\n\t<\/span>{\r\n\t<span>string<\/span> Name { <span>get<\/span>; }\r\n\t<span>void<\/span> Authenticate(UserInfo user, Credential credential);\r\n\tControl PromptControl { <span>get<\/span>; }\r\n\t}<\/pre>\n<\/div>\n<p style=\"padding-left: 30px\">Note that the PromptControl property above 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:<\/p>\n<ol style=\"padding-left: 60px\">\n<li><span class=\"codeInline\">MessagePrompt<\/span> (to display a simple message),<\/li>\n<li><span class=\"codeInline\">StringPrompt<\/span> (to input a one-time-password), and<\/li>\n<li><span class=\"codeInline\">NullPrompt<\/span> (does not display or require any additional input).<\/li>\n<\/ol>\n<p style=\"padding-left: 30px\">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.<\/p>\n<h3>Custom SMS Gateways<\/h3>\n<p>The SMS factor is designed to be extendable and allow for integration with alternate SMS gateway providers. This may be effectuated by deriving from <span class=\"codeInline\">BrandonHaynes.Membership.SmsFactor<\/span> and overriding one or more of the following methods:<\/p>\n<div>\n<pre><span>\/\/ Override this method to send a specific one-time password to a telephone <\/span>\r\n<span>\/\/ number for a particular user using whatever custom SMS gateway is desired.<\/span>\r\n<span>protected<\/span> <span>void<\/span> SendSms(UserInfo user, <span>string<\/span> telephone, <span>string<\/span> onetimePassword);<\/pre>\n<\/div>\n<div>\n<pre><span>\/\/ Override this method to format a given telephone number for transmission to a <\/span>\r\n<span>\/\/ custom SMS gateway service.  Note that the default implementation is <\/span>\r\n<span>\/\/ (unfortunately) US-centric and does not perform a robust E.164 formatting (code <\/span>\r\n<span>\/\/ submissions for this facet would be greatly appreciated!).  <\/span>\r\n<span>string<\/span> FormatTelephoneByCountry(UserInfo user, <span>string<\/span> telephone);<\/pre>\n<\/div>\n<h2>In Case of Emergency&#8230;<\/h2>\n<p>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.<\/p>\n<p>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.<\/p>\n<div>\n<pre><span>UPDATE<\/span> dbo.Authentication\r\n<span>SET<\/span> IsEnabled =\r\n\t<span>CASE<\/span> <span>WHEN<\/span> AuthenticationType = <span>'DNN'<\/span> <span>THEN<\/span> 1 <span>ELSE<\/span> 0 <span>END<\/span><\/pre>\n<\/div>\n<p>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 (thanks to <a href=\"http:\/\/www.mitchelsellers.com\/blogs.aspx\">Mitchel Sellers<\/a> for pointing out this oversight!).<\/p>\n<h2>Feedback Appreciated!<\/h2>\n<p>Feedback about your experiences is needed, and <span style=\"text-decoration: underline\">greatly<\/span> appreciated!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I am pleased to announce an initial release of a multi-factor provider for the DotNetNuke content management system. This authentication provider allows a host to configure enhanced authentication (including SMS, SMTP, YubiKey, and X.509 certificates) for any number and combination of portal roles. Each factor must be fulfilled prior to authentication being granted, increasing overall [&hellip;]<\/p>\n","protected":false},"author":1933,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3062,142],"tags":[5741,3070,19470,593,19469],"class_list":["post-50","post","type-post","status-publish","format-standard","hentry","category-dotnetnuke-dnn-content-management-system","category-technology","tag-authentication","tag-dotnetnuke","tag-dotnetnuke-dnn-content-management-system","tag-security","tag-technology"],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/archive.blogs.harvard.edu\/brandonhaynes\/wp-json\/wp\/v2\/posts\/50","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/archive.blogs.harvard.edu\/brandonhaynes\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/archive.blogs.harvard.edu\/brandonhaynes\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/archive.blogs.harvard.edu\/brandonhaynes\/wp-json\/wp\/v2\/users\/1933"}],"replies":[{"embeddable":true,"href":"https:\/\/archive.blogs.harvard.edu\/brandonhaynes\/wp-json\/wp\/v2\/comments?post=50"}],"version-history":[{"count":31,"href":"https:\/\/archive.blogs.harvard.edu\/brandonhaynes\/wp-json\/wp\/v2\/posts\/50\/revisions"}],"predecessor-version":[{"id":77,"href":"https:\/\/archive.blogs.harvard.edu\/brandonhaynes\/wp-json\/wp\/v2\/posts\/50\/revisions\/77"}],"wp:attachment":[{"href":"https:\/\/archive.blogs.harvard.edu\/brandonhaynes\/wp-json\/wp\/v2\/media?parent=50"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/archive.blogs.harvard.edu\/brandonhaynes\/wp-json\/wp\/v2\/categories?post=50"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/archive.blogs.harvard.edu\/brandonhaynes\/wp-json\/wp\/v2\/tags?post=50"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}