diff options
23 files changed, 691 insertions, 36 deletions
diff --git a/TwoStepsAuthenticator.TestWebsite/App_Start/FilterConfig.cs b/TwoStepsAuthenticator.TestWebsite/App_Start/FilterConfig.cs new file mode 100644 index 0000000..20a3374 --- /dev/null +++ b/TwoStepsAuthenticator.TestWebsite/App_Start/FilterConfig.cs @@ -0,0 +1,13 @@ +using System.Web; +using System.Web.Mvc; + +namespace TwoStepsAuthenticator.TestWebsite +{ + public class FilterConfig + { + public static void RegisterGlobalFilters(GlobalFilterCollection filters) + { + filters.Add(new HandleErrorAttribute()); + } + } +}
\ No newline at end of file diff --git a/TwoStepsAuthenticator.TestWebsite/App_Start/RouteConfig.cs b/TwoStepsAuthenticator.TestWebsite/App_Start/RouteConfig.cs new file mode 100644 index 0000000..cdacdd2 --- /dev/null +++ b/TwoStepsAuthenticator.TestWebsite/App_Start/RouteConfig.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.Mvc; +using System.Web.Routing; + +namespace TwoStepsAuthenticator.TestWebsite +{ + public class RouteConfig + { + public static void RegisterRoutes(RouteCollection routes) + { + routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); + + routes.MapRoute( + name: "Default", + url: "{controller}/{action}/{id}", + defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } + ); + } + } +}
\ No newline at end of file diff --git a/TwoStepsAuthenticator.TestWebsite/App_Start/WebApiConfig.cs b/TwoStepsAuthenticator.TestWebsite/App_Start/WebApiConfig.cs new file mode 100644 index 0000000..1ff1be7 --- /dev/null +++ b/TwoStepsAuthenticator.TestWebsite/App_Start/WebApiConfig.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web.Http; + +namespace TwoStepsAuthenticator.TestWebsite +{ + public static class WebApiConfig + { + public static void Register(HttpConfiguration config) + { + config.Routes.MapHttpRoute( + name: "DefaultApi", + routeTemplate: "api/{controller}/{id}", + defaults: new { id = RouteParameter.Optional } + ); + } + } +} diff --git a/TwoStepsAuthenticator.TestWebsite/Controllers/HomeController.cs b/TwoStepsAuthenticator.TestWebsite/Controllers/HomeController.cs new file mode 100644 index 0000000..c926019 --- /dev/null +++ b/TwoStepsAuthenticator.TestWebsite/Controllers/HomeController.cs @@ -0,0 +1,68 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.Mvc; +using System.Web.Security; +using TwoStepsAuthenticator.TestWebsite.Users; + +namespace TwoStepsAuthenticator.TestWebsite.Controllers +{ + public class HomeController : Controller + { + // + // GET: /Home/ + + public ActionResult Index() + { + return View(); + } + + [HttpPost] + public ActionResult Login(string login, string password) + { + if (Membership.ValidateUser(login, password)) + { + var user = WebsiteUserStorage.GetUser(login); + if (user.DoubleAuthActivated) + { + Session["AuthenticatedUser"] = user; + return View("DoubleAuth", user); + } + else + { + FormsAuthentication.SetAuthCookie(login, true); + return RedirectToAction("Welcome"); + } + } + return RedirectToAction("Index"); + } + + [HttpPost] + public ActionResult DoubleAuth(string code) + { + WebsiteUser user = (WebsiteUser)Session["AuthenticatedUser"]; + var auth = new TwoStepsAuthenticator.Authenticator(); + if (auth.CheckCode(user.DoubleAuthKey, code)) + { + FormsAuthentication.SetAuthCookie(user.Login, true); + return RedirectToAction("Welcome"); + } + + return RedirectToAction("Index"); + } + + [Authorize] + public ActionResult Welcome() + { + return View() ; + } + + [Authorize] + public ActionResult Logout() + { + FormsAuthentication.SignOut(); + return RedirectToAction("Index"); + } + } +} diff --git a/TwoStepsAuthenticator.TestWebsite/Global.asax b/TwoStepsAuthenticator.TestWebsite/Global.asax new file mode 100644 index 0000000..e0d7a7b --- /dev/null +++ b/TwoStepsAuthenticator.TestWebsite/Global.asax @@ -0,0 +1 @@ +<%@ Application Codebehind="Global.asax.cs" Inherits="TwoStepsAuthenticator.TestWebsite.MvcApplication" Language="C#" %> diff --git a/TwoStepsAuthenticator.TestWebsite/Global.asax.cs b/TwoStepsAuthenticator.TestWebsite/Global.asax.cs new file mode 100644 index 0000000..902168b --- /dev/null +++ b/TwoStepsAuthenticator.TestWebsite/Global.asax.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.Http; +using System.Web.Mvc; +using System.Web.Routing; + +namespace TwoStepsAuthenticator.TestWebsite +{ + // Note: For instructions on enabling IIS6 or IIS7 classic mode, + // visit http://go.microsoft.com/?LinkId=9394801 + public class MvcApplication : System.Web.HttpApplication + { + protected void Application_Start() + { + AreaRegistration.RegisterAllAreas(); + + WebApiConfig.Register(GlobalConfiguration.Configuration); + FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); + RouteConfig.RegisterRoutes(RouteTable.Routes); + } + } +}
\ No newline at end of file diff --git a/TwoStepsAuthenticator.TestWebsite/Properties/AssemblyInfo.cs b/TwoStepsAuthenticator.TestWebsite/Properties/AssemblyInfo.cs index b1e30d0..82e066b 100644 --- a/TwoStepsAuthenticator.TestWebsite/Properties/AssemblyInfo.cs +++ b/TwoStepsAuthenticator.TestWebsite/Properties/AssemblyInfo.cs @@ -20,7 +20,7 @@ using System.Runtime.InteropServices; [assembly: ComVisible(false)] // The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("1bef9786-7eb3-411d-8852-b4413ca2e71d")] +[assembly: Guid("48101b3a-bc0d-4a32-be34-4a36cbc47311")] // Version information for an assembly consists of the following four values: // diff --git a/TwoStepsAuthenticator.TestWebsite/TwoStepsAuthenticator.TestWebsite.csproj b/TwoStepsAuthenticator.TestWebsite/TwoStepsAuthenticator.TestWebsite.csproj index 68538de..48259f6 100644 --- a/TwoStepsAuthenticator.TestWebsite/TwoStepsAuthenticator.TestWebsite.csproj +++ b/TwoStepsAuthenticator.TestWebsite/TwoStepsAuthenticator.TestWebsite.csproj @@ -7,13 +7,14 @@ <ProductVersion> </ProductVersion> <SchemaVersion>2.0</SchemaVersion> - <ProjectGuid>{C61D3D65-5461-43E9-9E13-9DF85671ED27}</ProjectGuid> - <ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids> + <ProjectGuid>{38058CE1-D82E-4C9D-B07D-293EAEC66878}</ProjectGuid> + <ProjectTypeGuids>{E3E379DF-F4C6-4180-9B81-6769533ABE47};{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids> <OutputType>Library</OutputType> <AppDesignerFolder>Properties</AppDesignerFolder> <RootNamespace>TwoStepsAuthenticator.TestWebsite</RootNamespace> <AssemblyName>TwoStepsAuthenticator.TestWebsite</AssemblyName> <TargetFrameworkVersion>v4.5</TargetFrameworkVersion> + <MvcBuildViews>false</MvcBuildViews> <UseIISExpress>true</UseIISExpress> <IISExpressSSLPort /> <IISExpressAnonymousAuthentication /> @@ -39,36 +40,114 @@ </PropertyGroup> <ItemGroup> <Reference Include="Microsoft.CSharp" /> + <Reference Include="System" /> + <Reference Include="System.Data" /> + <Reference Include="System.Drawing" /> <Reference Include="System.Web.DynamicData" /> <Reference Include="System.Web.Entity" /> <Reference Include="System.Web.ApplicationServices" /> <Reference Include="System.ComponentModel.DataAnnotations" /> - <Reference Include="System" /> - <Reference Include="System.Data" /> <Reference Include="System.Core" /> <Reference Include="System.Data.DataSetExtensions" /> - <Reference Include="System.Web.Extensions" /> <Reference Include="System.Xml.Linq" /> - <Reference Include="System.Drawing" /> <Reference Include="System.Web" /> + <Reference Include="System.Web.Extensions" /> + <Reference Include="System.Web.Abstractions" /> + <Reference Include="System.Web.Routing" /> <Reference Include="System.Xml" /> <Reference Include="System.Configuration" /> <Reference Include="System.Web.Services" /> <Reference Include="System.EnterpriseServices" /> + <Reference Include="Microsoft.Web.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> + <Private>True</Private> + <HintPath>..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll</HintPath> + </Reference> + <Reference Include="Microsoft.Web.Mvc.FixedDisplayModes, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> + <Private>True</Private> + <HintPath>..\packages\Microsoft.AspNet.Mvc.FixedDisplayModes.1.0.0\lib\net40\Microsoft.Web.Mvc.FixedDisplayModes.dll</HintPath> + </Reference> + <Reference Include="Newtonsoft.Json"> + <HintPath>..\packages\Newtonsoft.Json.4.5.11\lib\net40\Newtonsoft.Json.dll</HintPath> + </Reference> + <Reference Include="System.Net.Http"> + </Reference> + <Reference Include="System.Net.Http.Formatting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.AspNet.WebApi.Client.4.0.20710.0\lib\net40\System.Net.Http.Formatting.dll</HintPath> + </Reference> + <Reference Include="System.Net.Http.WebRequest"> + </Reference> + <Reference Include="System.Web.Helpers, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> + <Private>True</Private> + <HintPath>..\packages\Microsoft.AspNet.WebPages.2.0.20710.0\lib\net40\System.Web.Helpers.dll</HintPath> + </Reference> + <Reference Include="System.Web.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.AspNet.WebApi.Core.4.0.20710.0\lib\net40\System.Web.Http.dll</HintPath> + </Reference> + <Reference Include="System.Web.Http.WebHost, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> + <HintPath>..\packages\Microsoft.AspNet.WebApi.WebHost.4.0.20710.0\lib\net40\System.Web.Http.WebHost.dll</HintPath> + </Reference> + <Reference Include="System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> + <Private>True</Private> + <HintPath>..\packages\Microsoft.AspNet.Mvc.4.0.20710.0\lib\net40\System.Web.Mvc.dll</HintPath> + </Reference> + <Reference Include="System.Web.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> + <Private>True</Private> + <HintPath>..\packages\Microsoft.AspNet.Razor.2.0.20715.0\lib\net40\System.Web.Razor.dll</HintPath> + </Reference> + <Reference Include="System.Web.WebPages, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> + <Private>True</Private> + <HintPath>..\packages\Microsoft.AspNet.WebPages.2.0.20710.0\lib\net40\System.Web.WebPages.dll</HintPath> + </Reference> + <Reference Include="System.Web.WebPages.Deployment, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> + <Private>True</Private> + <HintPath>..\packages\Microsoft.AspNet.WebPages.2.0.20710.0\lib\net40\System.Web.WebPages.Deployment.dll</HintPath> + </Reference> + <Reference Include="System.Web.WebPages.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> + <Private>True</Private> + <HintPath>..\packages\Microsoft.AspNet.WebPages.2.0.20710.0\lib\net40\System.Web.WebPages.Razor.dll</HintPath> + </Reference> </ItemGroup> <ItemGroup> - <Content Include="Web.config" /> - </ItemGroup> - <ItemGroup> + <Compile Include="Controllers\HomeController.cs" /> + <Compile Include="Users\CustomMembership.cs" /> + <Compile Include="Global.asax.cs"> + <DependentUpon>Global.asax</DependentUpon> + </Compile> <Compile Include="Properties\AssemblyInfo.cs" /> + <Compile Include="Users\WebsiteUser.cs" /> + <Compile Include="Users\WebsiteUserStorage.cs" /> </ItemGroup> <ItemGroup> - <None Include="Web.Debug.config"> + <Compile Include="App_Start\FilterConfig.cs" /> + <Compile Include="App_Start\RouteConfig.cs" /> + <Compile Include="App_Start\WebApiConfig.cs" /> + <Content Include="Global.asax" /> + <Content Include="Web.config" /> + <Content Include="Web.Debug.config"> <DependentUpon>Web.config</DependentUpon> - </None> - <None Include="Web.Release.config"> + </Content> + <Content Include="Web.Release.config"> <DependentUpon>Web.config</DependentUpon> - </None> + </Content> + <Content Include="Views\Web.config" /> + </ItemGroup> + <ItemGroup> + <Folder Include="App_Data\" /> + <Folder Include="Models\" /> + </ItemGroup> + <ItemGroup> + <Content Include="packages.config" /> + </ItemGroup> + <ItemGroup> + <Content Include="Views\Home\Index.cshtml" /> + </ItemGroup> + <ItemGroup> + <Content Include="Views\Shared\Error.cshtml" /> + <Content Include="Views\Shared\_Layout.cshtml" /> + <Content Include="Views\_ViewStart.cshtml" /> + </ItemGroup> + <ItemGroup> + <Content Include="Views\Home\DoubleAuth.cshtml" /> </ItemGroup> <ItemGroup> <ProjectReference Include="..\TwoStepsAuthenticator\TwoStepsAuthenticator.csproj"> @@ -76,6 +155,9 @@ <Name>TwoStepsAuthenticator</Name> </ProjectReference> </ItemGroup> + <ItemGroup> + <Content Include="Views\Home\Welcome.cshtml" /> + </ItemGroup> <PropertyGroup> <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion> <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath> @@ -83,6 +165,9 @@ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" /> <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" /> + <Target Name="MvcBuildViews" AfterTargets="AfterBuild" Condition="'$(MvcBuildViews)'=='true'"> + <AspNetCompiler VirtualPath="temp" PhysicalPath="$(WebProjectOutputDir)" /> + </Target> <ProjectExtensions> <VisualStudio> <FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}"> @@ -106,6 +191,5 @@ <Target Name="BeforeBuild"> </Target> <Target Name="AfterBuild"> - </Target> - --> + </Target> --> </Project>
\ No newline at end of file diff --git a/TwoStepsAuthenticator.TestWebsite/Users/CustomMembership.cs b/TwoStepsAuthenticator.TestWebsite/Users/CustomMembership.cs new file mode 100644 index 0000000..4c2cc59 --- /dev/null +++ b/TwoStepsAuthenticator.TestWebsite/Users/CustomMembership.cs @@ -0,0 +1,157 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.Security; + +namespace TwoStepsAuthenticator.TestWebsite.Users +{ + public class CustomMembership : MembershipProvider + { + public override string ApplicationName + { + get + { + throw new NotImplementedException(); + } + set + { + throw new NotImplementedException(); + } + } + + public override bool ChangePassword(string username, string oldPassword, string newPassword) + { + throw new NotImplementedException(); + } + + public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer) + { + throw new NotImplementedException(); + } + + public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status) + { + throw new NotImplementedException(); + } + + public override bool DeleteUser(string username, bool deleteAllRelatedData) + { + throw new NotImplementedException(); + } + + public override bool EnablePasswordReset + { + get { throw new NotImplementedException(); } + } + + public override bool EnablePasswordRetrieval + { + get { throw new NotImplementedException(); } + } + + public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords) + { + throw new NotImplementedException(); + } + + public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords) + { + throw new NotImplementedException(); + } + + public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords) + { + throw new NotImplementedException(); + } + + public override int GetNumberOfUsersOnline() + { + throw new NotImplementedException(); + } + + public override string GetPassword(string username, string answer) + { + throw new NotImplementedException(); + } + + public override MembershipUser GetUser(string username, bool userIsOnline) + { + throw new NotImplementedException(); + } + + public override MembershipUser GetUser(object providerUserKey, bool userIsOnline) + { + throw new NotImplementedException(); + } + + public override string GetUserNameByEmail(string email) + { + throw new NotImplementedException(); + } + + public override int MaxInvalidPasswordAttempts + { + get { throw new NotImplementedException(); } + } + + public override int MinRequiredNonAlphanumericCharacters + { + get { throw new NotImplementedException(); } + } + + public override int MinRequiredPasswordLength + { + get { throw new NotImplementedException(); } + } + + public override int PasswordAttemptWindow + { + get { throw new NotImplementedException(); } + } + + public override MembershipPasswordFormat PasswordFormat + { + get { throw new NotImplementedException(); } + } + + public override string PasswordStrengthRegularExpression + { + get { throw new NotImplementedException(); } + } + + public override bool RequiresQuestionAndAnswer + { + get { throw new NotImplementedException(); } + } + + public override bool RequiresUniqueEmail + { + get { throw new NotImplementedException(); } + } + + public override string ResetPassword(string username, string answer) + { + throw new NotImplementedException(); + } + + public override bool UnlockUser(string userName) + { + throw new NotImplementedException(); + } + + public override void UpdateUser(MembershipUser user) + { + throw new NotImplementedException(); + } + + public override bool ValidateUser(string username, string password) + { + if (String.IsNullOrEmpty(username) || String.IsNullOrEmpty(password)) + return false; + + var user = WebsiteUserStorage.GetUser(username); + return user != null && user.Password == password; + } + } +}
\ No newline at end of file diff --git a/TwoStepsAuthenticator.TestWebsite/Users/WebsiteUser.cs b/TwoStepsAuthenticator.TestWebsite/Users/WebsiteUser.cs new file mode 100644 index 0000000..2cc6cc9 --- /dev/null +++ b/TwoStepsAuthenticator.TestWebsite/Users/WebsiteUser.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; + +namespace TwoStepsAuthenticator.TestWebsite.Users +{ + public class WebsiteUser + { + public WebsiteUser(string login, string password, string key) + { + Login = login; + Password = password; + DoubleAuthKey = key; + } + + public string Login { get; set; } + + public string Password { get; set; } + + public string DoubleAuthKey { get; set; } + + public bool DoubleAuthActivated + { + get { return !String.IsNullOrEmpty(DoubleAuthKey); } + } + + } +}
\ No newline at end of file diff --git a/TwoStepsAuthenticator.TestWebsite/Users/WebsiteUserStorage.cs b/TwoStepsAuthenticator.TestWebsite/Users/WebsiteUserStorage.cs new file mode 100644 index 0000000..dc4d261 --- /dev/null +++ b/TwoStepsAuthenticator.TestWebsite/Users/WebsiteUserStorage.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; + +namespace TwoStepsAuthenticator.TestWebsite.Users +{ + public class WebsiteUserStorage + { + private static Dictionary<String, WebsiteUser> users; + + static WebsiteUserStorage() + { + users = new Dictionary<String, WebsiteUser>(); + + users.Add("user1", + new WebsiteUser("user1", "user1", "AAAAAAAAAAAAAAAA")); + + users.Add("user2", + new WebsiteUser("user2", "user2", "BBBBBBBBBBBBBBBB")); + + users.Add("user3", + new WebsiteUser("user3", "user3", null)); + } + + public static WebsiteUser GetUser(string login) + { + if (users.ContainsKey(login)) + return users[login]; + return null; + } + + } +}
\ No newline at end of file diff --git a/TwoStepsAuthenticator.TestWebsite/Views/Home/DoubleAuth.cshtml b/TwoStepsAuthenticator.TestWebsite/Views/Home/DoubleAuth.cshtml new file mode 100644 index 0000000..e864721 --- /dev/null +++ b/TwoStepsAuthenticator.TestWebsite/Views/Home/DoubleAuth.cshtml @@ -0,0 +1,16 @@ +@model TwoStepsAuthenticator.TestWebsite.Users.WebsiteUser + +@{ + ViewBag.Title = "DoubleAuth"; +} + +<h2>DoubleAuth</h2> + +@using (Html.BeginForm("DoubleAuth", "Home", FormMethod.Post)) +{ + <div> + <input type="text" name="code" /> + <br /> + <input type="submit" value="Submit"/> + </div> +}
\ No newline at end of file diff --git a/TwoStepsAuthenticator.TestWebsite/Views/Home/Index.cshtml b/TwoStepsAuthenticator.TestWebsite/Views/Home/Index.cshtml new file mode 100644 index 0000000..65c97de --- /dev/null +++ b/TwoStepsAuthenticator.TestWebsite/Views/Home/Index.cshtml @@ -0,0 +1,39 @@ +@{ + ViewBag.Title = "Index"; +} + +<h2>Double authentication test website</h2> + +<div> + Welcome to the double authentication test website. + <br /> + You can log-in with the following users :<br /> + login : "user1", password : "user1"<br /> + login : "user2", password : "user2"<br /> + login : "user3", password : "user3"<br /> + <br /> + <br /> + In order to login with user1 and user2, you have to set up an authenticator app : Microsoft Authenticator on Windows Phone, or Google authenticator on Android and iPhone. + <br /> + The secret key is "AAAAAAAAAAAAAAAA" (16 'A') for user1, + <br /> + and "BBBBBBBBBBBBBBBB" (16 'B') for user 2. + <br /> + user3 doesn't have double authentication enabled, so you will be able to log in directly. + + +</div> +<hr /> + +@using (Html.BeginForm("Login", "Home", FormMethod.Post)) +{ + <div> + Login : + <input type="text" name="login" /> + </div> + <div> + Password : + <input type="password" name="password" /> + </div> + <input type="submit" value="Submit" /> +}
\ No newline at end of file diff --git a/TwoStepsAuthenticator.TestWebsite/Views/Home/Welcome.cshtml b/TwoStepsAuthenticator.TestWebsite/Views/Home/Welcome.cshtml new file mode 100644 index 0000000..c5132a6 --- /dev/null +++ b/TwoStepsAuthenticator.TestWebsite/Views/Home/Welcome.cshtml @@ -0,0 +1,10 @@ +@{ + ViewBag.Title = "Welcome"; +} + +<h2>Welcome</h2> + +You are logged in the website +<br /> + +@Html.ActionLink("log out", "Logout")
\ No newline at end of file diff --git a/TwoStepsAuthenticator.TestWebsite/Views/Shared/Error.cshtml b/TwoStepsAuthenticator.TestWebsite/Views/Shared/Error.cshtml new file mode 100644 index 0000000..b4a1239 --- /dev/null +++ b/TwoStepsAuthenticator.TestWebsite/Views/Shared/Error.cshtml @@ -0,0 +1,17 @@ +@{ + Layout = null; +} + +<!DOCTYPE html> +<html> +<head> + <meta name="viewport" content="width=device-width" /> + <title>Error</title> +</head> +<body> + <hgroup> + <h1>Error.</h1> + <h2>An error occurred while processing your request.</h2> + </hgroup> +</body> +</html>
\ No newline at end of file diff --git a/TwoStepsAuthenticator.TestWebsite/Views/Shared/_Layout.cshtml b/TwoStepsAuthenticator.TestWebsite/Views/Shared/_Layout.cshtml new file mode 100644 index 0000000..917898d --- /dev/null +++ b/TwoStepsAuthenticator.TestWebsite/Views/Shared/_Layout.cshtml @@ -0,0 +1,11 @@ +<!DOCTYPE html> +<html> +<head> + <meta charset="utf-8" /> + <meta name="viewport" content="width=device-width" /> + <title>@ViewBag.Title</title> +</head> +<body> + @RenderBody() +</body> +</html> diff --git a/TwoStepsAuthenticator.TestWebsite/Views/Web.config b/TwoStepsAuthenticator.TestWebsite/Views/Web.config new file mode 100644 index 0000000..826ce19 --- /dev/null +++ b/TwoStepsAuthenticator.TestWebsite/Views/Web.config @@ -0,0 +1,58 @@ +<?xml version="1.0"?> + +<configuration> + <configSections> + <sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"> + <section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" /> + <section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" /> + </sectionGroup> + </configSections> + + <system.web.webPages.razor> + <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> + <pages pageBaseType="System.Web.Mvc.WebViewPage"> + <namespaces> + <add namespace="System.Web.Mvc" /> + <add namespace="System.Web.Mvc.Ajax" /> + <add namespace="System.Web.Mvc.Html" /> + <add namespace="System.Web.Routing" /> + </namespaces> + </pages> + </system.web.webPages.razor> + + <appSettings> + <add key="webpages:Enabled" value="false" /> + </appSettings> + + <system.web> + <httpHandlers> + <add path="*" verb="*" type="System.Web.HttpNotFoundHandler"/> + </httpHandlers> + + <!-- + Enabling request validation in view pages would cause validation to occur + after the input has already been processed by the controller. By default + MVC performs request validation before a controller processes the input. + To change this behavior apply the ValidateInputAttribute to a + controller or action. + --> + <pages + validateRequest="false" + pageParserFilterType="System.Web.Mvc.ViewTypeParserFilter, System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" + pageBaseType="System.Web.Mvc.ViewPage, System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" + userControlBaseType="System.Web.Mvc.ViewUserControl, System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"> + <controls> + <add assembly="System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" namespace="System.Web.Mvc" tagPrefix="mvc" /> + </controls> + </pages> + </system.web> + + <system.webServer> + <validation validateIntegratedModeConfiguration="false" /> + + <handlers> + <remove name="BlockViewHandler"/> + <add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" /> + </handlers> + </system.webServer> +</configuration> diff --git a/TwoStepsAuthenticator.TestWebsite/Views/_ViewStart.cshtml b/TwoStepsAuthenticator.TestWebsite/Views/_ViewStart.cshtml new file mode 100644 index 0000000..efda124 --- /dev/null +++ b/TwoStepsAuthenticator.TestWebsite/Views/_ViewStart.cshtml @@ -0,0 +1,3 @@ +@{ + Layout = "~/Views/Shared/_Layout.cshtml"; +}
\ No newline at end of file diff --git a/TwoStepsAuthenticator.TestWebsite/Web.Debug.config b/TwoStepsAuthenticator.TestWebsite/Web.Debug.config index 2e302f9..3e2a97c 100644 --- a/TwoStepsAuthenticator.TestWebsite/Web.Debug.config +++ b/TwoStepsAuthenticator.TestWebsite/Web.Debug.config @@ -1,12 +1,12 @@ -<?xml version="1.0" encoding="utf-8"?> +<?xml version="1.0"?> -<!-- For more information on using web.config transformation visit http://go.microsoft.com/fwlink/?LinkId=125889 --> +<!-- For more information on using Web.config transformation visit http://go.microsoft.com/fwlink/?LinkId=125889 --> <configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform"> <!-- In the example below, the "SetAttributes" transform will change the value of "connectionString" to use "ReleaseSQLServer" only when the "Match" locator - finds an attribute "name" that has a value of "MyDB". + finds an atrribute "name" that has a value of "MyDB". <connectionStrings> <add name="MyDB" @@ -17,7 +17,7 @@ <system.web> <!-- In the example below, the "Replace" transform will replace the entire - <customErrors> section of your web.config file. + <customErrors> section of your Web.config file. Note that because there is only one customErrors section under the <system.web> node, there is no need to use the "xdt:Locator" attribute. diff --git a/TwoStepsAuthenticator.TestWebsite/Web.Release.config b/TwoStepsAuthenticator.TestWebsite/Web.Release.config index c358444..9fd481f 100644 --- a/TwoStepsAuthenticator.TestWebsite/Web.Release.config +++ b/TwoStepsAuthenticator.TestWebsite/Web.Release.config @@ -1,12 +1,12 @@ -<?xml version="1.0" encoding="utf-8"?> +<?xml version="1.0"?> -<!-- For more information on using web.config transformation visit http://go.microsoft.com/fwlink/?LinkId=125889 --> +<!-- For more information on using Web.config transformation visit http://go.microsoft.com/fwlink/?LinkId=125889 --> <configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform"> <!-- In the example below, the "SetAttributes" transform will change the value of "connectionString" to use "ReleaseSQLServer" only when the "Match" locator - finds an attribute "name" that has a value of "MyDB". + finds an atrribute "name" that has a value of "MyDB". <connectionStrings> <add name="MyDB" @@ -18,7 +18,7 @@ <compilation xdt:Transform="RemoveAttributes(debug)" /> <!-- In the example below, the "Replace" transform will replace the entire - <customErrors> section of your web.config file. + <customErrors> section of your Web.config file. Note that because there is only one customErrors section under the <system.web> node, there is no need to use the "xdt:Locator" attribute. diff --git a/TwoStepsAuthenticator.TestWebsite/Web.config b/TwoStepsAuthenticator.TestWebsite/Web.config index 6da78ec..1aac16b 100644 --- a/TwoStepsAuthenticator.TestWebsite/Web.config +++ b/TwoStepsAuthenticator.TestWebsite/Web.config @@ -1,14 +1,49 @@ -<?xml version="1.0"?> - +<?xml version="1.0" encoding="utf-8"?> <!-- For more information on how to configure your ASP.NET application, please visit http://go.microsoft.com/fwlink/?LinkId=169433 --> <configuration> - <system.web> - <compilation debug="true" targetFramework="4.5" /> - <httpRuntime targetFramework="4.5" /> - </system.web> + <appSettings> + <add key="webpages:Version" value="2.0.0.0" /> + <add key="webpages:Enabled" value="false" /> + <add key="PreserveLoginUrl" value="true" /> + <add key="ClientValidationEnabled" value="true" /> + <add key="UnobtrusiveJavaScriptEnabled" value="true" /> + </appSettings> + + <system.web> + + <httpRuntime targetFramework="4.5" /> + + <compilation debug="true" targetFramework="4.5" /> + + <pages> + <namespaces> + <add namespace="System.Web.Helpers" /> + <add namespace="System.Web.Mvc" /> + <add namespace="System.Web.Mvc.Ajax" /> + <add namespace="System.Web.Mvc.Html" /> + <add namespace="System.Web.Routing" /> + <add namespace="System.Web.WebPages" /> + </namespaces> + </pages> + + <authentication mode="Forms" /> + + <membership defaultProvider="CustomMembership" userIsOnlineTimeWindow="15"> + <providers> + <clear /> + <add + name="CustomMembership" + type="TwoStepsAuthenticator.TestWebsite.Users.CustomMembership" /> + </providers> + </membership> + </system.web> + <system.webServer> + <validation validateIntegratedModeConfiguration="false" /> + + <handlers><remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" /><remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" /><remove name="ExtensionlessUrlHandler-Integrated-4.0" /><add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" /><add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" /><add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" /></handlers></system.webServer> </configuration> diff --git a/TwoStepsAuthenticator.TestWebsite/packages.config b/TwoStepsAuthenticator.TestWebsite/packages.config new file mode 100644 index 0000000..f02c507 --- /dev/null +++ b/TwoStepsAuthenticator.TestWebsite/packages.config @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="utf-8"?> +<packages> + <package id="Microsoft.AspNet.Mvc" version="4.0.20710.0" targetFramework="net45" /> + <package id="Microsoft.AspNet.Mvc.FixedDisplayModes" version="1.0.0" targetFramework="net45" /> + <package id="Microsoft.AspNet.Razor" version="2.0.20715.0" targetFramework="net45" /> + <package id="Microsoft.AspNet.WebApi" version="4.0.20710.0" targetFramework="net45" /> + <package id="Microsoft.AspNet.WebApi.Client" version="4.0.20710.0" targetFramework="net45" /> + <package id="Microsoft.AspNet.WebApi.Core" version="4.0.20710.0" targetFramework="net45" /> + <package id="Microsoft.AspNet.WebApi.WebHost" version="4.0.20710.0" targetFramework="net45" /> + <package id="Microsoft.AspNet.WebPages" version="2.0.20710.0" targetFramework="net45" /> + <package id="Microsoft.Net.Http" version="2.0.20710.0" targetFramework="net45" /> + <package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net45" /> + <package id="Newtonsoft.Json" version="4.5.11" targetFramework="net45" /> +</packages>
\ No newline at end of file diff --git a/TwoStepsAuthenticator.sln b/TwoStepsAuthenticator.sln index b69b71c..a23c14e 100644 --- a/TwoStepsAuthenticator.sln +++ b/TwoStepsAuthenticator.sln @@ -1,22 +1,18 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2012 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TwoStepsAuthenticator.TestWebsite", "TwoStepsAuthenticator.TestWebsite\TwoStepsAuthenticator.TestWebsite.csproj", "{C61D3D65-5461-43E9-9E13-9DF85671ED27}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TwoStepsAuthenticator", "TwoStepsAuthenticator\TwoStepsAuthenticator.csproj", "{6C898CD1-0BF3-4711-847E-AD7DAC815CD8}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TwoStepsAuthenticator.TestApp", "TwoStepsAuthenticator.TestApp\TwoStepsAuthenticator.TestApp.csproj", "{53C4F81C-4322-4637-B79B-8676ACAEFDCB}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TwoStepsAuthenticator.TestWebsite", "TwoStepsAuthenticator.TestWebsite\TwoStepsAuthenticator.TestWebsite.csproj", "{38058CE1-D82E-4C9D-B07D-293EAEC66878}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {C61D3D65-5461-43E9-9E13-9DF85671ED27}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C61D3D65-5461-43E9-9E13-9DF85671ED27}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C61D3D65-5461-43E9-9E13-9DF85671ED27}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C61D3D65-5461-43E9-9E13-9DF85671ED27}.Release|Any CPU.Build.0 = Release|Any CPU {6C898CD1-0BF3-4711-847E-AD7DAC815CD8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {6C898CD1-0BF3-4711-847E-AD7DAC815CD8}.Debug|Any CPU.Build.0 = Debug|Any CPU {6C898CD1-0BF3-4711-847E-AD7DAC815CD8}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -25,6 +21,10 @@ Global {53C4F81C-4322-4637-B79B-8676ACAEFDCB}.Debug|Any CPU.Build.0 = Debug|Any CPU {53C4F81C-4322-4637-B79B-8676ACAEFDCB}.Release|Any CPU.ActiveCfg = Release|Any CPU {53C4F81C-4322-4637-B79B-8676ACAEFDCB}.Release|Any CPU.Build.0 = Release|Any CPU + {38058CE1-D82E-4C9D-B07D-293EAEC66878}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {38058CE1-D82E-4C9D-B07D-293EAEC66878}.Debug|Any CPU.Build.0 = Debug|Any CPU + {38058CE1-D82E-4C9D-B07D-293EAEC66878}.Release|Any CPU.ActiveCfg = Release|Any CPU + {38058CE1-D82E-4C9D-B07D-293EAEC66878}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE |