<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-2016746845209941562</id><updated>2026-09-21T03:33:03.250-04:00</updated><category term="ASP.Net"/><category term="C#"/><category term="VoiceXML"/><category term="VoiceModel"/><category term="MVC 4"/><category term="MVC"/><category term="IVR"/><category term="security"/><category term="SimpleMembership"/><category term="Tropo"/><category term="Voxeo"/><category term="Prophecy"/><category term="ASP.NET Identity"/><category term="MVC 5"/><category term="Razor"/><category term="open source"/><category term="Twilio"/><category term="Reusable Dialog Components"/><category term="SCXML"/><category term="Web API"/><category term="architecture"/><category term="Entity Framework"/><category term="SimpleSecurity"/><category term="debug"/><category term="design"/><category term="design patterns"/><category term="state machine"/><category term="test"/><category term=".NET Core"/><category term="AJAX"/><category term="Google"/><category term="MVVM"/><category term="Mayhem"/><category term="Portable Areas"/><category term="RDC"/><category term="code-first"/><category term="home automation"/><category term="voice"/><category term="API"/><category term="DotNetNuke"/><category term="Fiddler"/><category term="NuGet"/><category term="REST"/><category term="VUI"/><category term="Visual Studio 2012"/><category term="Visual Studio 2017"/><category term="WIF"/><category term="WebMatrix"/><category term="call flow"/><category term="notification"/><category term="outbound"/><category term="rules engine"/><category term="speech recognition"/><category term="two-factor authentication"/><category term="workflow"/><title type='text'>Kevin Junghans</title><subtitle type='html'>Disruptive Communications on Software</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://kevin-junghans.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2016746845209941562/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://kevin-junghans.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/2016746845209941562/posts/default?start-index=26&amp;max-results=25&amp;redirect=false'/><author><name>Kevin Junghans</name><uri>http://www.blogger.com/profile/01125287678342544067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>64</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-2016746845209941562.post-6836783469343098538</id><published>2017-08-27T21:14:00.000-04:00</published><updated>2017-08-28T10:16:19.983-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term=".NET Core"/><category scheme="http://www.blogger.com/atom/ns#" term="ASP.Net"/><category scheme="http://www.blogger.com/atom/ns#" term="ASP.NET Identity"/><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="security"/><category scheme="http://www.blogger.com/atom/ns#" term="Visual Studio 2017"/><title type='text'>Customizing Claims for Authorization in ASP.NET Core 2.0</title><content type='html'>There have been some major changes to ASP.NET Identity with the release of Core 2.0, which you can &lt;a href=&quot;https://docs.microsoft.com/en-us/aspnet/core/migration/1x-to-2x/identity-2x&quot; target=&quot;_blank&quot;&gt;read about here&lt;/a&gt;. &amp;nbsp;One of the major changes is that it does not rely on using middleware anymore to customize it. &amp;nbsp;Instead dependency injection is used by configuring via services in the &lt;i&gt;ConfigureServices &lt;/i&gt;method of &lt;i&gt;StartUp.cs&lt;/i&gt;. &amp;nbsp; There is not much documentation or examples on how to do this so I am going to explore how to customize ASP.NET Identity and publish some examples in this blog. &amp;nbsp;First I wanted to look at how you would add custom claims to the identity and then use those claims for authorization.&lt;br /&gt;
&lt;br /&gt;
To begin create a new &lt;i&gt;ASP.NET Core Web Application&lt;/i&gt;&amp;nbsp;project in Visual Studio 2017. &amp;nbsp;Be sure to select .&lt;i&gt;NET Core&lt;/i&gt; and &lt;i&gt;ASP.NET Core 2.0&lt;/i&gt; in the two drop downs at the top. &amp;nbsp;Select the template for Web Application (Model-View-Controller) and &lt;i&gt;Change the Authentication&lt;/i&gt; to&lt;i&gt; Individual User Accounts&lt;/i&gt;. &amp;nbsp;When the project is created you are ready to add some code.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1aj5FYrJUcDep55HKIMVI2SYUXgd0JjJV82wbmhiYic8P6rcRLoMigO_48Hdm-60PdDSoVOKqwGdS2JpTT7QVDecEva8KV46chZbvjsdebJurOpPCbZajRmCI_dXF5NWmoVguQ7M1Ov8/s1600/CreateNewWebApp.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;650&quot; data-original-width=&quot;1000&quot; height=&quot;260&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1aj5FYrJUcDep55HKIMVI2SYUXgd0JjJV82wbmhiYic8P6rcRLoMigO_48Hdm-60PdDSoVOKqwGdS2JpTT7QVDecEva8KV46chZbvjsdebJurOpPCbZajRmCI_dXF5NWmoVguQ7M1Ov8/s400/CreateNewWebApp.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
For this example we are simply restricting access to an Administration page to administrators only. &amp;nbsp;To indicate that the user is an administrator &amp;nbsp;add a property to the &lt;i&gt;ApplicationUser &lt;/i&gt;which is a boolean named &lt;i&gt;IsAdminsitrator&lt;/i&gt;. &amp;nbsp;You will find the &lt;i&gt;ApplicationUser &lt;/i&gt;class in &lt;i&gt;Models/ApplicationUser.cs&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;    public class ApplicationUser : IdentityUser
    {
        public bool IsAdministrator { get; set; }
    }
&lt;/pre&gt;
&lt;br /&gt;
Next we need to create a custom&amp;nbsp;&lt;i&gt;UserClaimsPrincipalFactory &lt;/i&gt;that creates a new claim that indicates if the user is an administrator or not. &lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;    public class MyClaimsPrincipalFactory&amp;lt;TUser&amp;gt;: UserClaimsPrincipalFactory&amp;lt;TUser&amp;gt; where TUser : ApplicationUser
    {
        public MyClaimsPrincipalFactory(
            UserManager&amp;lt;TUser&amp;gt; userManager,
            IOptions&amp;lt;IdentityOptions&amp;gt; optionsAccessor) : base(userManager, optionsAccessor)
        {
 
        }

        protected override async Task&amp;lt;ClaimsIdentity&amp;gt; GenerateClaimsAsync(TUser user)
        {
            var id = await base.GenerateClaimsAsync(user);
            id.AddClaim(new Claim(MyClaimTypes.IsAdmin, user.IsAdministrator.ToString().ToLower()));
            return id;
        }
    }
&lt;/pre&gt;
&lt;br /&gt;
Define the claim type in a class so that it can be reused later and avoid the problems caused by magic strings.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt; public class MyClaimTypes
 {
     public const string IsAdmin = &quot;http://myclaims.com/claims/isadmin&quot;;
 }
&lt;/pre&gt;
&lt;br /&gt;
Use dependency injection in ASP.NET Core to configure the custom claims principal factory you just created by adding this line the &lt;i&gt;ConfigureServices&lt;/i&gt; method of &lt;i&gt;Startup.cs&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;  services.AddTransient&amp;lt;IUserClaimsPrincipalFactory&amp;lt;ApplicationUser&amp;gt;, MyClaimsPrincipalFactory&amp;lt;ApplicationUser&amp;gt;&amp;gt;();
&lt;/pre&gt;
&lt;br /&gt;
Now when the identity pipeline performs authentication it will call the custom claims principal factory and add the custom claims we will need for authorization. &amp;nbsp;With Core we no longer create custom AuthorizeAttributes to handle the claims. Instead you need to create a custom policy. &amp;nbsp;This is a fairly simple policy so we can add it like this in the ConfigureServices method of Startup.cs.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;    services.AddAuthorization(options =&amp;gt;
    {
        options.AddPolicy(&quot;AdminsOnly&quot;, policy =&amp;gt; policy.RequireClaim(MyClaimTypes.IsAdmin, &quot;true&quot;));
    });
&lt;/pre&gt;
&lt;br /&gt;
In this simple policy we are just checking to see if the custom claim of type&amp;nbsp;&lt;i&gt;IsAdmin &lt;/i&gt;is set to either true or false. &amp;nbsp;Now to test this add a custom view for Administrators and add an Authorize attribute like this.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;    [Authorize(Policy = &quot;AdminsOnly&quot;)]
    public IActionResult Administration()
    {
        ViewData[&quot;Message&quot;] = &quot;Page for application administration.&quot;;
        return View();
    }
&lt;/pre&gt;
&lt;br /&gt;
Now whenever this view is invoked the &lt;i&gt;AdminsOnly&lt;/i&gt; policy will be checked to if the identity has a claim type of &lt;i&gt;IsAdmin &lt;/i&gt;that is set to true or not. &amp;nbsp;If it is true the user will have access, otherwise they will not have access. &amp;nbsp;Fire up this web application and try it out. &amp;nbsp;Give the user access to this new view or not by setting the column &lt;i&gt;IsAdministrator &lt;/i&gt;in the &lt;i&gt;AspNetUsers &lt;/i&gt;table for the user you are testing. &amp;nbsp;When you are testing keep in mind that the change to the user will not take place as soon as the change in the database table. &amp;nbsp;You will need to sign the user out and back in again for it to take affect. &amp;nbsp;There is a way to handle keeping your logged in users in sync with database changes when using Core Identity. &amp;nbsp;We will explore that in future blog posts.&lt;br /&gt;
&lt;br /&gt;
So that is all there is to add a custom claim that we can use for authorization of users. &amp;nbsp;This method &amp;nbsp;using policies for authorization works great if the logic is simple, but you can hit road blocks when the authorization logic gets more complex. &amp;nbsp;Look for future blogs where we will explore how to handle more complex authorizations. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
 SyntaxHighlighter.highlight();
&lt;/script&gt;</content><link rel='replies' type='application/atom+xml' href='http://kevin-junghans.blogspot.com/feeds/6836783469343098538/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kevin-junghans.blogspot.com/2017/08/customizing-claims-for-authorization-in.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2016746845209941562/posts/default/6836783469343098538'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2016746845209941562/posts/default/6836783469343098538'/><link rel='alternate' type='text/html' href='http://kevin-junghans.blogspot.com/2017/08/customizing-claims-for-authorization-in.html' title='Customizing Claims for Authorization in ASP.NET Core 2.0'/><author><name>Kevin Junghans</name><uri>http://www.blogger.com/profile/01125287678342544067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1aj5FYrJUcDep55HKIMVI2SYUXgd0JjJV82wbmhiYic8P6rcRLoMigO_48Hdm-60PdDSoVOKqwGdS2JpTT7QVDecEva8KV46chZbvjsdebJurOpPCbZajRmCI_dXF5NWmoVguQ7M1Ov8/s72-c/CreateNewWebApp.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2016746845209941562.post-6773324121609919032</id><published>2017-04-07T15:54:00.000-04:00</published><updated>2017-04-07T15:54:10.625-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term=".NET Core"/><category scheme="http://www.blogger.com/atom/ns#" term="ASP.Net"/><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="MVC"/><category scheme="http://www.blogger.com/atom/ns#" term="Tropo"/><category scheme="http://www.blogger.com/atom/ns#" term="Twilio"/><category scheme="http://www.blogger.com/atom/ns#" term="VoiceModel"/><category scheme="http://www.blogger.com/atom/ns#" term="VoiceXML"/><title type='text'>CodePlex is Dead. Long Live GitHub</title><content type='html'>I was very sad to hear about the &lt;a href=&quot;https://blogs.msdn.microsoft.com/bharry/2017/03/31/shutting-down-codeplex/&quot; target=&quot;_blank&quot;&gt;demise of CodePlex&lt;/a&gt;. &amp;nbsp;I had a couple of open source projects on their site and I loved the tools provided to manage a project, especially the tight integration with Visual Studio. &amp;nbsp;But alas all good things must come to an end. &amp;nbsp;Always looking for a positive aspect to all situations, I decided that on the plus side this will force me to learn how to use Git for version control.&lt;br /&gt;
&lt;br /&gt;
I have heard for some time all of the buzz around using Git but was quite content with using Team Foundation Version Control (TFVC). &amp;nbsp;But even Microsoft is embracing Git and has offered it as an option in Visual Studio for some time now and seems to get all of the new functionality when it come to version control. &amp;nbsp;Each takes a very different approach to version control, with Git being a distributed solution whereas TFVC is a centralized solution. &amp;nbsp;Microsoft has a good discussion comparing the two and when to use each in this article, &lt;i&gt;&lt;a href=&quot;https://www.visualstudio.com/en-us/docs/tfvc/comparison-git-tfvc&quot; target=&quot;_blank&quot;&gt;Choosing the right version control for your project&lt;/a&gt;&lt;/i&gt;. &amp;nbsp; I can see where Git can be a better fit for open source projects.&lt;br /&gt;
&lt;br /&gt;
So I am going to revive one of my old open source projects on CodePlex and move it to GitHub. The Project is VoiceModel and you can now find it &lt;a href=&quot;https://github.com/kjunghans/VoiceModel&quot; target=&quot;_blank&quot;&gt;here on GitHub&lt;/a&gt;. &amp;nbsp;The project has been dormant for a while but I have been getting some requests to move it to .NET Core and Visual Studio 2017. &amp;nbsp;I think that will be a great project to make the product more portable and improve performance. &amp;nbsp;With the popularity of &lt;a href=&quot;https://www.twilio.com/&quot; target=&quot;_blank&quot;&gt;Twilio &lt;/a&gt;I am also thinking about adding support for this platform.&lt;br /&gt;
&lt;br /&gt;
For those not familiar with VoiceModel it is a project that makes it easier to develop &lt;a href=&quot;https://www.w3.org/TR/voicexml20/&quot; target=&quot;_blank&quot;&gt;VoiceXML &lt;/a&gt;and &lt;a href=&quot;https://www.tropo.com/&quot; target=&quot;_blank&quot;&gt;Tropo&lt;/a&gt; speech applications using ASP.Net MVC and Razor. VoiceModel uses the MVVM (Model-View-VoiceModel) design pattern to abstract the voice application to a higher level and decouples the voice user interface from the application domain and call flow. VoiceModel also supports Reusable Dialog Components (RDC) which allow you to build modules that can be reused across voice applications for increased productivity. It also has a built-in easy to use state machine that allow you to easily define your call flow. With VoiceModel you can develop your voice application once and deploy it for any VoiceXML compatible IVR or the Tropo Cloud IVR.&lt;br /&gt;
&lt;br /&gt;
I am excited to revive this project and will be sharing on this blog what I learn about using GitHub for open source projects and moving VoiceModel to .NET Core. &amp;nbsp;So stay tuned. &amp;nbsp;And if you are interested in contributing visit the &lt;a href=&quot;https://github.com/kjunghans/VoiceModel&quot; target=&quot;_blank&quot;&gt;VoiceModel on GitHub&lt;/a&gt;.</content><link rel='replies' type='application/atom+xml' href='http://kevin-junghans.blogspot.com/feeds/6773324121609919032/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kevin-junghans.blogspot.com/2017/04/codeplex-is-dead-long-live-github.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2016746845209941562/posts/default/6773324121609919032'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2016746845209941562/posts/default/6773324121609919032'/><link rel='alternate' type='text/html' href='http://kevin-junghans.blogspot.com/2017/04/codeplex-is-dead-long-live-github.html' title='CodePlex is Dead. Long Live GitHub'/><author><name>Kevin Junghans</name><uri>http://www.blogger.com/profile/01125287678342544067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2016746845209941562.post-8590125521267667352</id><published>2014-10-06T09:52:00.000-04:00</published><updated>2014-10-06T09:52:53.557-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ASP.Net"/><category scheme="http://www.blogger.com/atom/ns#" term="ASP.NET Identity"/><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="security"/><category scheme="http://www.blogger.com/atom/ns#" term="SimpleSecurity"/><category scheme="http://www.blogger.com/atom/ns#" term="Tropo"/><category scheme="http://www.blogger.com/atom/ns#" term="two-factor authentication"/><title type='text'>Recent Updates to SimpleSecurity</title><content type='html'>The latest bits for &lt;a href=&quot;http://simplesecurity.codeplex.com/SourceControl/latest&quot; target=&quot;_blank&quot;&gt;SimpleSecurity &lt;/a&gt;have been updated to include the Manage controller, which allows users to change their password and their external logons. &amp;nbsp;This was a major request by readers of this blog. &amp;nbsp;It will also be the place where users will configure &lt;a href=&quot;http://lifehacker.com/5938565/heres-everywhere-you-should-enable-two-factor-authentication-right-now&quot; target=&quot;_blank&quot;&gt;two-factor authentication&lt;/a&gt;. &amp;nbsp;This will be the next feature added to SimpleSecurity and it will support email, SMS, and phone. &lt;br /&gt;
&lt;br /&gt;
So watch these pages for a post on how to add two-factor authentication with ASP.NET Identity that supports email, SMS, and phone. &amp;nbsp;With all of the cyber security attacks these days you should seriously consider adding two-factor authentication to your web site.</content><link rel='replies' type='application/atom+xml' href='http://kevin-junghans.blogspot.com/feeds/8590125521267667352/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kevin-junghans.blogspot.com/2014/10/recent-updates-to-simplesecurity.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2016746845209941562/posts/default/8590125521267667352'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2016746845209941562/posts/default/8590125521267667352'/><link rel='alternate' type='text/html' href='http://kevin-junghans.blogspot.com/2014/10/recent-updates-to-simplesecurity.html' title='Recent Updates to SimpleSecurity'/><author><name>Kevin Junghans</name><uri>http://www.blogger.com/profile/01125287678342544067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2016746845209941562.post-8846431379106722176</id><published>2014-05-03T11:48:00.000-04:00</published><updated>2014-05-03T11:48:17.943-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ASP.NET Identity"/><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="MVC 5"/><category scheme="http://www.blogger.com/atom/ns#" term="security"/><title type='text'>Using External Logins with ASP.NET Identity</title><content type='html'>A feature request for &lt;a href=&quot;https://simplesecurity.codeplex.com/&quot; target=&quot;_blank&quot;&gt;SimpleSecurity &lt;/a&gt;has been the &lt;a href=&quot;https://simplesecurity.codeplex.com/workitem/1303&quot; target=&quot;_blank&quot;&gt;ability to support external logins&lt;/a&gt;. &amp;nbsp;This has been completed and by default it supports login with a Google account. &amp;nbsp;Google login is enabled because it does not require setup of any accounts on the provider side. &amp;nbsp;In order to enable other social logins, like Facebook, &lt;a href=&quot;http://www.asp.net/web-api/overview/security/external-authentication-services&quot; target=&quot;_blank&quot;&gt;follow this tutorial for ASP.NET Identity&lt;/a&gt;, which will work the same way in SimpleSecurity.&lt;br /&gt;
&lt;br /&gt;
As part of this process I have also upgraded SimpleSecurity to ASP.NET Identity 2.0. &amp;nbsp;This version of ASP.NET Identity has added missing features that SimpleSecurity already provided, such as email confirmation and password reset. &amp;nbsp;It has also added some other beneficial features that you can&lt;a href=&quot;http://blogs.msdn.com/b/webdev/archive/2014/03/20/test-announcing-rtm-of-asp-net-identity-2-0-0.aspx&quot; target=&quot;_blank&quot;&gt; read about here&lt;/a&gt;. &amp;nbsp;Watch for future posts in this blog that will compare how the ASP.NET Identity team implemented email confirmation compared to SimpleSecurity, and I explore some of the other new features.&lt;br /&gt;
&lt;br /&gt;
For those that have not been following the evolution of SimpleSecurity it originally was developed as a reference implementation on how to decouple SimpleMembership from an MVC application and to add missing features. &amp;nbsp;To make the transition as easy as possible the API for SimpleSecurity mimicked the &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/webmatrix.webdata.websecurity(v=vs.111).aspx&quot; target=&quot;_blank&quot;&gt;WebSecurity &lt;/a&gt;class used in SimpleMembership, and just like the original it was made a static class. &amp;nbsp;When ASP.NET Identity became available another implementation was developed with this security framework under the hood, and again the same WebSecurity facade was used. &amp;nbsp;As some readers pointed out making the API with a static class made it next to impossible to use IoC and DI. &amp;nbsp;Therefore the WebSecurity class is no longer static and it inherits from IDisposable for proper cleanup of the UserManager when it is out of scope. &amp;nbsp;Check out these changes and let me know what you think.&lt;br /&gt;
&lt;br /&gt;
Back to external logins. I had one reader ask for a tutorial on how to tie external logins and local logins together. The example given was that a user initially sets up a local account but then decides they would rather use their Facebook account to login. &amp;nbsp;How do we allow the user to now login with the Facebook account and they would still have access to the same profile and user information they had available in the local account. I started to look into this and wondered if other sites allowed for this.&lt;br /&gt;
&lt;br /&gt;
I found an example in CodePlex, where SimpleSecurity can be found. &amp;nbsp;I have had a local CodePlex account for years and they recently added the ability to logon with your Microsoft Live account. &amp;nbsp;I tried creating a login with Microsoft Live. &amp;nbsp;After logging in with Microsft Live I was prompted to either login with my local CodePlex account, to tie the two together, or register as a new user. I found the user experience to be very good. &amp;nbsp;But I did not complete the process because I am still concerned about the use of social logins.&lt;br /&gt;
&lt;br /&gt;
What do you think? &amp;nbsp;Is this good way to implement this feature that is secure? &amp;nbsp;Is this a useful feature? &amp;nbsp;Some people even&lt;a href=&quot;https://blog.mailchimp.com/social-login-buttons-arent-worth-it/&quot; target=&quot;_blank&quot;&gt; question the benefits of social logins&lt;/a&gt;&amp;nbsp;and believe they are not secure. Think about it. If someone hacks into your social account now they have access to every system that you login with that account. &amp;nbsp;Don&#39;t think it can happen to you? &lt;a href=&quot;http://www.wired.com/2012/08/apple-amazon-mat-honan-hacking/all/&quot; target=&quot;_blank&quot;&gt;Read about this person&#39;s nightmare here&lt;/a&gt;. What are your thought? &amp;nbsp;I am interested in hearing from you.&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://kevin-junghans.blogspot.com/feeds/8846431379106722176/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kevin-junghans.blogspot.com/2014/05/using-external-logins-with-aspnet.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2016746845209941562/posts/default/8846431379106722176'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2016746845209941562/posts/default/8846431379106722176'/><link rel='alternate' type='text/html' href='http://kevin-junghans.blogspot.com/2014/05/using-external-logins-with-aspnet.html' title='Using External Logins with ASP.NET Identity'/><author><name>Kevin Junghans</name><uri>http://www.blogger.com/profile/01125287678342544067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2016746845209941562.post-8021588999811755083</id><published>2014-03-15T16:40:00.000-04:00</published><updated>2014-03-15T16:43:46.773-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ASP.Net"/><category scheme="http://www.blogger.com/atom/ns#" term="ASP.NET Identity"/><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="MVC 5"/><category scheme="http://www.blogger.com/atom/ns#" term="security"/><title type='text'>Performing Authorization In Class Libraries Without Coupling Security in ASP.NET Identity</title><content type='html'>Most of the time it makes sense to perform authorization at the Controller or Web API level in an ASP.NET MVC application using an &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.web.mvc.authorizeattribute(v=vs.118).aspx&quot; target=&quot;_blank&quot;&gt;&lt;i&gt;AuthorizeAttribute &lt;/i&gt;&lt;/a&gt;on the controller or action. &amp;nbsp;This handles at least 95% of the scenarios but occasionally it makes sense to handle authorization down in a class library or it needs to be handled in code for more complex situations. An example might be an application that allows users to create folders and files that have individual permissions. &amp;nbsp;In this scenario the resource being acted upon must be determined at run-time and therefore we cannot use a static AuthorizeAttribute.&lt;br /&gt;
&lt;br /&gt;
So how do we determine permissions on a dynamic resource without coupling security with our application domain. This is a good time to use a custom &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.security.claims.claimsauthorizationmanager(v=vs.110).aspx&quot; target=&quot;_blank&quot;&gt;&lt;i&gt;ClaimsAuthorizationManager&lt;/i&gt;&lt;/a&gt;. &amp;nbsp; A &lt;i&gt;ClaimsAuthorizationManager&lt;/i&gt; will allow a class library to loosely couple authorization in our application domain and configure it at deployment. &amp;nbsp;Here is an example on using the &lt;i&gt;ClaimsAuthorizationManager&lt;/i&gt; that I added to the &lt;a href=&quot;http://simplesecurity.codeplex.com/&quot; target=&quot;_blank&quot;&gt;SimpleSecurity project&lt;/a&gt;&amp;nbsp;using ASP.NET Identity. &amp;nbsp;You can get the &lt;a href=&quot;http://simplesecurity.codeplex.com/SourceControl/latest#AspNetIdentity/SimpleSecurity.AspNetIdentity/SimpleAuthorizationManager.cs&quot; target=&quot;_blank&quot;&gt;source code for this example here&lt;/a&gt;. 
&lt;br /&gt;
&lt;br /&gt;
Here is how we would insert an authorization check in our class library.
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;    public class FakeService
    {
        public static void MyMethod()
        {
            //Here is where we would check access to perform operations in this method.
            ClaimsPrincipalPermission.CheckAccess(AppResources.Foo.ToString(), Operations.Read.ToString());
            //If we made it this far we were authorized and we would perform the actual operations here.
        }
    }
&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
When calling the &lt;i&gt;ClaimsAuthorizationManager &lt;/i&gt;you invoke the &lt;i&gt;CheckAccess &lt;/i&gt;method which expects two parameters; a resource and an action.  This provides context to the ClaimsAuthorizationManager on what to authorize.  In this contrived example the resource and action are static, but as you can imagine they could just as easily have been derived from something like a database query or other application logic.  Notice that the resource and action passed in fit nicely with the concepts I presented in an earlier &lt;a href=&quot;http://kevin-junghans.blogspot.com/2013/09/decoupling-your-security-model-revisited.html&quot; target=&quot;_blank&quot;&gt;article on decoupling the security model from your MVC application&lt;/a&gt;. If the authorization fails the &lt;i&gt;ClaimsAuthorizationManager&lt;/i&gt; throws a &lt;i&gt;SecurityException &lt;/i&gt;which we can handle in our controller or Web API.
&lt;br /&gt;
&lt;br /&gt;
What makes this method of authorization even more flexible is that we configure which &lt;i&gt;ClaimsAuthorizationManager &lt;/i&gt;to use in the web.config.  Here is what the configuration looks like for this example.
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: xml&quot;&gt; &amp;lt;system.identityModel&amp;gt;
    &amp;lt;identityConfiguration&amp;gt;
      &amp;lt;claimsAuthorizationManager type=&quot;SimpleSecurity.AspNetIdentity.SimpleAuthorizationManager, SimpleSecurity.AspNetIdentity&quot;/&amp;gt;
    &amp;lt;/identityConfiguration&amp;gt;
  &amp;lt;/system.identityModel&amp;gt;
&lt;/pre&gt;
&lt;br /&gt;
This allows us to configure different &lt;i&gt;ClaimsAuthorizationManagers &lt;/i&gt;for different web applications, further decoupling the authorization process from our application domain.&lt;br /&gt;
&lt;br /&gt;
Here is what the code look like for this custom &lt;i&gt;ClaimsAuthorizationManager&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;    public class SimpleAuthorizationManager : ClaimsAuthorizationManager
    {
        public override bool CheckAccess(AuthorizationContext context)
        {
            string resourceStr = context.Resource.First().Value;
            string actionStr = context.Action.First().Value;
            int resourceId;
            Operations operationId;
            try { resourceId = Int32.Parse(resourceStr); }
            catch { throw new Exception(&quot;Invalid resource. Must be a string representation of an integer value.&quot;); }
            try { operationId = (Operations)Enum.Parse(typeof(Operations),actionStr); }
            catch { throw new Exception(&quot;Invalid action/operation. Must be a string representation of an integer value.&quot;); }

            //Get the current claims principal
            var prinicpal = (ClaimsPrincipal)Thread.CurrentPrincipal;
            //Make sure they are authenticated
            if (!prinicpal.Identity.IsAuthenticated)
                return false;
            //Get the roles from the claims
            var roles = prinicpal.Claims.Where(c =&amp;gt; c.Type == ClaimTypes.Role).Select(c =&amp;gt; c.Value).ToArray();
            //Check if they are authorized
            return ResourceService.Authorize(resourceId, operationId, roles);
        }
    }
&lt;/pre&gt;
&lt;br /&gt;
This authorization process gets the roles from the current authenticated users claims and checks in the database if any of those roles are associated with the resource and operation/action that is being performed.  The resource and action passed in are strings so I need to convert them to the integer ID and enumerated operation used in the database. 
&lt;br /&gt;
&lt;br /&gt;
If the authorization process fails a &lt;i&gt;SecurityException &lt;/i&gt;is thrown. Here is how we can catch the exception and handle it in the controller.
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;        public ActionResult UseClaimsAuthorization()
        {
            try
            {
                FakeService.MyMethod();
            }
            catch (SecurityException ex)
            {
                Response.Redirect(loginUrl(Url.Action(&quot;UseClaimsAuthorization&quot;, &quot;Home&quot;)));
            }
            ViewBag.Message = &quot;Test Claims Authorization&quot;;
            return View();
        }

        public string loginUrl(string returnUrl)
        {
             return &quot;../Account/Login?ReturnUrl=&quot; + HttpUtility.UrlEncode(returnUrl);
        }

&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;
In this example I handle the &lt;i&gt;SecurityException &lt;/i&gt;just like forms authentication would and redirect to the login page.  In a Web API you could return an HTTP Unauthorized error.
&lt;br /&gt;
&lt;br /&gt;
You can try this out by &lt;a href=&quot;http://simplesecurity.codeplex.com/SourceControl/latest&quot; target=&quot;_blank&quot;&gt;downloading the source code from SimpleSecurity&lt;/a&gt;, compiling and running the application. &amp;nbsp;The example MVC application is in &lt;i&gt;AspNetIdentity\SimpleSecurity.AspNetIdentity.RefApp&lt;/i&gt;. The database is seeded with a user who has a user name of &quot;user&quot; and password of &quot;password&quot; that has the role for the resource/operation authorized in this example.&lt;br /&gt;
&lt;br /&gt;
I think this is a good method for handling security in your class libraries and lower layers of the application without tightly coupling your security model.  What do you think? Can you think of some applications for this technique.
&lt;br /&gt;
&lt;br /&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
 SyntaxHighlighter.highlight();
&lt;/script&gt;</content><link rel='replies' type='application/atom+xml' href='http://kevin-junghans.blogspot.com/feeds/8021588999811755083/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kevin-junghans.blogspot.com/2014/03/performing-authorization-in-class.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2016746845209941562/posts/default/8021588999811755083'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2016746845209941562/posts/default/8021588999811755083'/><link rel='alternate' type='text/html' href='http://kevin-junghans.blogspot.com/2014/03/performing-authorization-in-class.html' title='Performing Authorization In Class Libraries Without Coupling Security in ASP.NET Identity'/><author><name>Kevin Junghans</name><uri>http://www.blogger.com/profile/01125287678342544067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2016746845209941562.post-1747362218500202735</id><published>2014-02-16T11:16:00.000-05:00</published><updated>2014-02-16T11:16:31.860-05:00</updated><title type='text'>Migrating an Existing Website from SimpleMembership to ASP.NET Identity (Update)</title><content type='html'>In a &lt;a href=&quot;http://kevin-junghans.blogspot.com/2014/02/migrating-existing-website-from.html&quot; target=&quot;_blank&quot;&gt;previous post &lt;/a&gt;I describe how to move the data from a SimpleMembership database to an ASP.NET Identity database. &amp;nbsp;After some more research I found that the ASP.NET Identity Team has put together a sample solution for migrating from SimpleMembership to ASP.NET Identity that includes some &lt;a href=&quot;https://aspnet.codeplex.com/SourceControl/latest#Samples/Identity/SimpleMembershipSchemeUpdateMigration/SimpleMembershipToIdentityMigration.sql&quot; target=&quot;_blank&quot;&gt;SQL scripts to assist with the migration&lt;/a&gt;. &amp;nbsp;Be sure to check out this &lt;a href=&quot;https://aspnet.codeplex.com/SourceControl/latest#Samples/Identity/SimpleMembershipSchemeUpdateMigration/readme.txt&quot; target=&quot;_blank&quot;&gt;solution on CodePlex&lt;/a&gt; if you are migrating your SimpleMembership website.&lt;br /&gt;
&lt;br /&gt;
I also realized in my previous post that I did not mention the benefit of using &lt;a href=&quot;http://simplesecurity.codeplex.com/&quot; target=&quot;_blank&quot;&gt;SimpleSecurity &lt;/a&gt;in your migration. &amp;nbsp;SimpleSecurity contains an implementation of ASP.NET Identity that has an API that is a super-set of the &lt;a href=&quot;http://simplesecurity.codeplex.com/SourceControl/latest#AspNetIdentity/SimpleSecurity.AspNetIdentity/WebSecurity.cs&quot; target=&quot;_blank&quot;&gt;WebSecurity&lt;/a&gt; class used in SimpleMembership. &amp;nbsp;This will allow you to plug in ASP.NET Identity into your existing code base with little to no changes. In addition it provides features such as email confirmation during registration and password reset that are not available in the initial release of ASP.NET Identity.&lt;br /&gt;
&lt;br /&gt;
Happy Migrations.</content><link rel='replies' type='application/atom+xml' href='http://kevin-junghans.blogspot.com/feeds/1747362218500202735/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kevin-junghans.blogspot.com/2014/02/migrating-existing-website-from_16.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2016746845209941562/posts/default/1747362218500202735'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2016746845209941562/posts/default/1747362218500202735'/><link rel='alternate' type='text/html' href='http://kevin-junghans.blogspot.com/2014/02/migrating-existing-website-from_16.html' title='Migrating an Existing Website from SimpleMembership to ASP.NET Identity (Update)'/><author><name>Kevin Junghans</name><uri>http://www.blogger.com/profile/01125287678342544067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2016746845209941562.post-5410793007829544344</id><published>2014-02-15T13:21:00.000-05:00</published><updated>2014-04-29T09:22:15.144-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ASP.Net"/><category scheme="http://www.blogger.com/atom/ns#" term="ASP.NET Identity"/><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="MVC 4"/><category scheme="http://www.blogger.com/atom/ns#" term="MVC 5"/><category scheme="http://www.blogger.com/atom/ns#" term="security"/><category scheme="http://www.blogger.com/atom/ns#" term="SimpleMembership"/><title type='text'>Migrating an Existing Website from SimpleMembership to ASP.NET Identity</title><content type='html'>&lt;a href=&quot;http://www.asp.net/identity&quot; target=&quot;_blank&quot;&gt;ASP.NET Identity&lt;/a&gt; is replacing SimpleMembership as the security/membership framework to use when creating ASP.NET applications. &amp;nbsp;If you are moving to MVC 5 and Visual Studio 2013 the ASP.NET templates generate code that uses ASP.NET Identity. &amp;nbsp;ASP.NET Identity is much more extensible than SimpleMembership is and it uses the new OWIN architecture available in MVC 5. &amp;nbsp;I think that ASP.NET Identity is an improvement over SimpleMembership and the old membership provider model that historically was used with ASP.NET applications. &amp;nbsp;The main problem I have with it is the lack of documentation that is currently available. &amp;nbsp;One article I was looking for in particular was how to migrate an existing website that uses SimpleMembership to ASP.NET Identity. &amp;nbsp;You can move to MVC 5 and keep using SimpleMembership as I &lt;a href=&quot;http://kevin-junghans.blogspot.com/2013/10/upgrading-web-application-using.html&quot; target=&quot;_blank&quot;&gt;wrote about here&lt;/a&gt;. &amp;nbsp;But what if you wanted to take advantage of benefits and features of ASP.NET Identity in a legacy website. &amp;nbsp;Microsoft wrote about&amp;nbsp;&lt;i&gt;&lt;a href=&quot;http://www.asp.net/identity/overview/migrations/migrating-an-existing-website-from-sql-membership-to-aspnet-identity&quot; target=&quot;_blank&quot;&gt;Migrating an Existing Website from SQL Membership to ASP.NET Identity&lt;/a&gt;&lt;/i&gt;, and&amp;nbsp;&lt;i&gt;&lt;a href=&quot;http://www.asp.net/identity/overview/migrations/migrating-universal-provider-data-for-membership-and-user-profiles-to-aspnet-identity&quot; target=&quot;_blank&quot;&gt;Migrating Universal Provider Data for Membership and User Profiles to ASP.NET Identity&lt;/a&gt;, &lt;/i&gt;but nothing on migrating SimpleMembership.&lt;br /&gt;
&lt;br /&gt;
So I researched this more and it turns out to be very simple (no pun intended) to migrate from SimpleMembership to ASP.NET Identity. The main issue with migrating is that you will need to move your existing membership data to the new database schema used by ASP.NET Identity. &amp;nbsp; And the password hash used by SimpleMembership must match the one used by ASP.NET Identity. &amp;nbsp;More on the password hash later.&lt;br /&gt;
&lt;br /&gt;
To move your data over you first need to create a custom &lt;b&gt;ApplicationUser&lt;/b&gt; that has the same properties as your &lt;b&gt;UserProfile &lt;/b&gt;in SimpleMembership. &amp;nbsp;For example, if your &lt;b&gt;UserProfile&lt;/b&gt; looked like this;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;    public class UserProfile
    {
        [Key]
        [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
        public int UserId { get; set; }
        public string UserName { get; set; }
        public string Email { get; set; }
    }
&lt;/pre&gt;
&lt;br /&gt;
Then your new &lt;b&gt;ApplicaitonUser&lt;/b&gt; class will look like this;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;    public class ApplicationUser : IdentityUser
    {
        public string Email { get; set; }
        public string ConfirmationToken { get; set; }
        public bool IsConfirmed { get; set; }
        public string PasswordResetToken { get; set; }
    }
&lt;/pre&gt;
&lt;br /&gt;
In this example the custom property added to UserProfile is Email. &amp;nbsp;You will notice that I did not add the properties UserId and UserName to the new ApplicationUser class. &amp;nbsp;That is because they are already defined in the class it inherits, IdentityUser. &amp;nbsp;The definition of IdentityUser looks like this.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;   public class IdentityUser : IUser
    {
        public IdentityUser();
        public IdentityUser(string userName);

        public virtual ICollection&amp;lt;IdentityUserClaim&amp;gt; Claims { get; }
        public virtual string Id { get; set; }
        public virtual ICollection&amp;lt;IdentityUserLogin&amp;gt; Logins { get; }
        public virtual string PasswordHash { get; set; }
        public virtual ICollection&amp;lt;IdentityUserRole&amp;gt; Roles { get; }
        public virtual string SecurityStamp { get; set; }
        public virtual string UserName { get; set; }
    }
&lt;/pre&gt;
&lt;br /&gt;
&lt;b&gt;UserName &lt;/b&gt;is a direct map from &lt;b&gt;UserProfile&lt;/b&gt; to &lt;b&gt;ApplicationUser&lt;/b&gt;. You will notice that the &lt;b&gt;Id &lt;/b&gt;for &lt;b&gt;IdentityUser &lt;/b&gt;is a string. &amp;nbsp;You will have to account for this in the scripts or application used to import the existing data when you map&lt;b&gt; UserProfile.UserId&lt;/b&gt; to &lt;b&gt;ApplicationUser.Id&lt;/b&gt;. &lt;br /&gt;
&lt;br /&gt;
ASP.NET Identity flattens the table layout by keeping all of the membership data in a single table called &lt;b&gt;AspNetUsers&lt;/b&gt;. &amp;nbsp;In SimpleMembership there were two tables, &lt;b&gt;UserProfile&lt;/b&gt; and &lt;b&gt;webpages_Membership&lt;/b&gt;. &amp;nbsp;&lt;b&gt;webpages_Membership&lt;/b&gt; contained information like the &lt;b&gt;Password&lt;/b&gt;, &lt;b&gt;IsConfirmed&lt;/b&gt; and &lt;b&gt;ConfirmationToken&lt;/b&gt;. &amp;nbsp;So when mapping passwords you will need to map &lt;b&gt;webpagesMembership.Password&lt;/b&gt; to &lt;b&gt;AspNetUsers.PasswordHash&lt;/b&gt;. &amp;nbsp;SimpleMembership had a &lt;b&gt;PasswordSalt &lt;/b&gt;field, but it was never used. More on that later. &amp;nbsp;The &lt;b&gt;IsConfirmed &lt;/b&gt;and &lt;b&gt;ConfirmationToken&lt;/b&gt; are not available in &lt;b&gt;IdentityUser &lt;/b&gt;so that is why I added them to the &lt;b&gt;ApplicationUser &lt;/b&gt;class.&amp;nbsp;You only need to add these if you are&lt;a href=&quot;http://kevin-junghans.blogspot.com/2013/02/adding-email-confirmation-to.html&quot; target=&quot;_blank&quot;&gt; using email confirmation in SimpleMembership&lt;/a&gt; or are &lt;a href=&quot;http://kevin-junghans.blogspot.com/2013/10/adding-email-confirmation-to-aspnet.html&quot; target=&quot;_blank&quot;&gt;planning on using it going forward&lt;/a&gt;. &amp;nbsp;&amp;nbsp;The same goes for&amp;nbsp;&lt;b&gt;PasswordResetToken&lt;/b&gt;&amp;nbsp;used for&amp;nbsp;&lt;a href=&quot;http://kevin-junghans.blogspot.com/2013/04/password-reset-with-simplemembership.html&quot; target=&quot;_blank&quot;&gt;password resets&lt;/a&gt;. &lt;br /&gt;
&lt;br /&gt;
Once you have &lt;b&gt;ApplicationUser&lt;/b&gt; defined to mimic your custom &lt;b&gt;UserProfile &lt;/b&gt;in SimpleMembership, create the new database, and run your import script or application. If you were using roles you will need to import the role data as well. &amp;nbsp;It is pretty straight map from &lt;b&gt;wepages_Roles &lt;/b&gt;to &lt;b&gt;AspNetRoles &lt;/b&gt;except while the id&#39;s for &lt;b&gt;webpages_Roles&lt;/b&gt; is an int they id in &lt;b&gt;AspNetRoles &lt;/b&gt;is nvarchar(128). &amp;nbsp;The same applies when mapping &lt;b&gt;wepages_UsersInRoles &lt;/b&gt;to &lt;b&gt;AspNetUserRoles&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
So now you have all of your old SimpleMembership data in your shiny new ASP.NET Identity tables will it work without further modifications. This will only work if the password hash used by SimpleSecurity is the same as ASP.NET Identity. &amp;nbsp;Well it turns out they are the same.&lt;br /&gt;
&lt;br /&gt;
At first glance I thought they were different because entering the same password in SimpleSecurity gave different results when entered into ASP.NET Identity. &amp;nbsp;The fact that the &lt;b&gt;PasswordSalt&lt;/b&gt; field was empty should have been a clue to what I was seeing. &amp;nbsp;I did some research and found that SimpleMembership uses&amp;nbsp;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.web.helpers.crypto(v=vs.111).aspx&quot;&gt;&lt;b&gt;System.Web.Helpers.Crypto&lt;/b&gt;&lt;/a&gt; to hash and verify the passwords. &amp;nbsp;To hash the password the method &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.web.helpers.crypto.hashpassword(v=vs.111).aspx&quot;&gt;&lt;b&gt;HashPassword &lt;/b&gt;&lt;/a&gt;is used.&amp;nbsp;The password hash is generated with the RFC 2898 algorithm using a 128-bit salt, a 256-bit subkey, and 1000 iterations. The format of the generated hash bytestream is {0x00, salt, subkey}, which is base-64 encoded before it is returned. &amp;nbsp;So the reason it was different each time was that this method creates a new salt each time and it is encoded in what I thought was just the straight password hash. I then ran a quick test to validate that ASP.NET Identity could verify a password hash from SimpleMembership and it worked perfectly.&lt;br /&gt;
&lt;br /&gt;
What if they did use different password hash algorithms. &amp;nbsp;It is very easy to plug in your own password hasher in ASP.NET Identity. &amp;nbsp;First you just write a class that implements the&amp;nbsp;&lt;b&gt;IPasswordHasher &lt;/b&gt;interface. &amp;nbsp;Here is one that uses the password hasher used by SimpleMembership.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt; 
    public class SimplePasswordHasher : IPasswordHasher
    {
        public string HashPassword(string password)
        {
            return Crypto.HashPassword(password);
        }

        public PasswordVerificationResult VerifyHashedPassword(string hashedPassword, string providedPassword)
        {
            if(Crypto.VerifyHashedPassword(hashedPassword, providedPassword))
                return PasswordVerificationResult.Success;
            else return PasswordVerificationResult.Failed;
        }
    }
&lt;/pre&gt;
&lt;br /&gt;
And here is how we plug it into the &lt;b&gt;AccountController&lt;/b&gt;.
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt; 
        public AccountController(UserManager&amp;lt;ApplicationUser&amp;gt; userManager)
        {
            userManager.PasswordHasher = new SimplePasswordHasher();
            UserManager = userManager;
        }
&lt;/pre&gt;
&lt;br /&gt;
So all we have to do to migrate our SimpleMembership website to ASP.NET Identity is create an &lt;b&gt;ApplicationUser &lt;/b&gt;class that mimic the old &lt;b&gt;UserProfile&lt;/b&gt; class and move the data over. Simple, isn&#39;t it.&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://kevin-junghans.blogspot.com/2014/02/migrating-existing-website-from_16.html&quot; target=&quot;_blank&quot;&gt;&lt;b&gt;&lt;i&gt;Checkout an update to this article here.&lt;/i&gt;&lt;/b&gt;&lt;/a&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
 SyntaxHighlighter.highlight();
&lt;/script&gt;</content><link rel='replies' type='application/atom+xml' href='http://kevin-junghans.blogspot.com/feeds/5410793007829544344/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kevin-junghans.blogspot.com/2014/02/migrating-existing-website-from.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2016746845209941562/posts/default/5410793007829544344'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2016746845209941562/posts/default/5410793007829544344'/><link rel='alternate' type='text/html' href='http://kevin-junghans.blogspot.com/2014/02/migrating-existing-website-from.html' title='Migrating an Existing Website from SimpleMembership to ASP.NET Identity'/><author><name>Kevin Junghans</name><uri>http://www.blogger.com/profile/01125287678342544067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2016746845209941562.post-3817898749036040842</id><published>2013-12-05T14:34:00.000-05:00</published><updated>2014-03-16T10:56:43.340-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ASP.NET Identity"/><category scheme="http://www.blogger.com/atom/ns#" term="MVC 5"/><category scheme="http://www.blogger.com/atom/ns#" term="security"/><title type='text'>Using Claims in ASP.NET Identity</title><content type='html'>&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ff359101.aspx&quot; target=&quot;_blank&quot;&gt;Claims &lt;/a&gt;can simplify and increase the performance of authentication and authorization processes. I wrote about how you can &lt;a href=&quot;http://kevin-junghans.blogspot.com/2013/10/improving-performance-of.html&quot; target=&quot;_blank&quot;&gt;use the roles stored as claims to eliminate back-end queries every time authorization takes place&lt;/a&gt;. &amp;nbsp;ASP.NET Identity has good support for claims-based identity and it creates several claims for you automatically when you create a new identity. &amp;nbsp;Here is how we create the identity for a new user during the log-in process&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;UserManager&amp;lt;applicationuser&amp;gt; userManager = new UserManager&amp;lt;applicationuser&amp;gt;(new UserStore&amp;lt;applicationuser&amp;gt;(new SecurityContext()));
ClaimsIdentity identity = userManager.CreateIdentity(user, DefaultAuthenticationTypes.ApplicationCookie);
&lt;/pre&gt;
&lt;br /&gt;
If you inspect the &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.security.claims.claimsidentity.claims(v=vs.110).aspx&quot; target=&quot;_blank&quot;&gt;&lt;i&gt;Claims &lt;/i&gt;&lt;/a&gt;property of &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.security.claims.claimsidentity(v=vs.110).aspx&quot; target=&quot;_blank&quot;&gt;&lt;i&gt;ClaimsIdentity &lt;/i&gt;&lt;/a&gt;after calling &lt;i&gt;CreateIdentity &lt;/i&gt;you will see that there are there are three or more claims.  There is a claim for the user ID, user name, identity provider and one for each role assigned. So what if you want to add some more claims? Here is an example of how to add the email as a claim.
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;var user = userManager.Find(userName, password);
identity.AddClaim(new Claim(ClaimTypes.Email, user.Email));
&lt;/pre&gt;
&lt;br /&gt;
&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.identitymodel.claims.claimtypes(v=vs.110).aspx&quot; target=&quot;_blank&quot;&gt;&lt;i&gt;ClaimTypes &lt;/i&gt;&lt;/a&gt;is an object that contains constant strings that represent the claim type. These are usually in the format of a URI. For example the Email type is &quot;http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress&quot;. If you want to add a claim that is not represented in the &lt;i&gt;ClaimTypes &lt;/i&gt;object then you can use your own string to represent the type. I usually create a static object of my own to store any custom types.  You will need to know what that constant string is when you query for the claim.  Here is how we get the email claim from an identity.
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;var prinicpal = (ClaimsPrincipal)Thread.CurrentPrincipal;
var email = prinicpal.Claims.Where(c =&amp;gt; c.Type == ClaimTypes.Email).Select(c =&amp;gt; c.Value).SingleOrDefault();
&lt;/pre&gt;
&lt;br /&gt;
So how was the custom email claim saved in the CurrentPrincipal and persisted in the cookie? It is when we call the SignIn method to complete the log-in process, passing in the identity we created with the custom claim added.
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = persistCookie }, identity);
&lt;/pre&gt;
&lt;br /&gt;
Using claims-based identity is very easy in ASP.NET Identity.  But don&#39;t get carried away shoving everything about the user in as a claim. I would only keep it to items needed for authorization or that are accessed often in the application for the current user.  How would you use claims-based identity in your applications?
&lt;br /&gt;
&lt;br /&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
 SyntaxHighlighter.highlight();
&lt;/script&gt;</content><link rel='replies' type='application/atom+xml' href='http://kevin-junghans.blogspot.com/feeds/3817898749036040842/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kevin-junghans.blogspot.com/2013/12/using-claims-in-aspnet-identity.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2016746845209941562/posts/default/3817898749036040842'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2016746845209941562/posts/default/3817898749036040842'/><link rel='alternate' type='text/html' href='http://kevin-junghans.blogspot.com/2013/12/using-claims-in-aspnet-identity.html' title='Using Claims in ASP.NET Identity'/><author><name>Kevin Junghans</name><uri>http://www.blogger.com/profile/01125287678342544067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2016746845209941562.post-6067011232984348945</id><published>2013-12-05T11:42:00.000-05:00</published><updated>2013-12-05T11:42:05.725-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ASP.NET Identity"/><category scheme="http://www.blogger.com/atom/ns#" term="MVC 5"/><category scheme="http://www.blogger.com/atom/ns#" term="security"/><category scheme="http://www.blogger.com/atom/ns#" term="Web API"/><title type='text'>Returning 401 HTTP Status Code on Authentication Failure in MVC 5 Web API&#39;s</title><content type='html'>The behavior of how a Web API responds to authentication/authorization exceptions has significantly changed in MVC 5. First, a little background. In a previous article I demonstrated &lt;a href=&quot;http://kevin-junghans.blogspot.com/2013/02/mixing-forms-authentication-basic.html&quot; target=&quot;_blank&quot;&gt;how to create a custom AuthorizeAttribute that mixes basic authentication with forms authentication&lt;/a&gt;&amp;nbsp;when using Web API&#39;s. &amp;nbsp; This custom attribute was designed to return an HTTP status code of 401 (Unauthorized) if authentication failed and a 403 (Forbidden) if the user is not authorized. &amp;nbsp;The example code was written as part of the &lt;a href=&quot;https://simplesecurity.codeplex.com/&quot; target=&quot;_blank&quot;&gt;SimpleSecurity Project&lt;/a&gt;, which was originally written to decouple and enhance the ASP.NET membership provider SimpleMembership. &amp;nbsp;I recently&lt;a href=&quot;http://kevin-junghans.blogspot.com/2013/11/decoupling-aspnet-identify-from-your.html&quot; target=&quot;_blank&quot;&gt; ported this code to work with the new ASP.NET Identity&lt;/a&gt; which replaces SimpleMembership in MVC 5. &amp;nbsp;It turns out that during my testing of the port I did not do a good job of testing error conditions. Bad tester.&lt;br /&gt;
&lt;br /&gt;
The security pipeline in OWIN and MVC 5 has changed and the custom attribute was no longer returning 401 and 403 status codes. Instead it was returning a 200 status code and inserting some additional information in the header.
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;X-Responded-JSON: {&quot;status&quot;:401,&quot;headers&quot;:{&quot;location&quot;:&quot;http:\/\/localhost:59540\/Account\/Login?ReturnUrl=%2Fapi%2FTestBasic&quot;}}
&lt;/pre&gt;
&lt;br /&gt;
So now the status code is in the header as part of this JSON object and it also contain the URL for the login page so that we can redirect to it.  We could just change the logic in our client JavaScript to support this change and just get the status from the header and handle it accordingly.  But if you want your application to behave the same way it was in MVC 4 there is a solution. I found the &lt;a href=&quot;http://brockallen.com/2013/10/27/using-cookie-authentication-middleware-with-web-api-and-401-response-codes/&quot; target=&quot;_blank&quot;&gt;solution in this article&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
You need to modify the code in your Startup.Auth.cs file to have it return the status codes you set in the response. &amp;nbsp;Here is what the updated code looks like.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;    public partial class Startup
    {
        private static bool IsAjaxRequest(IOwinRequest request)
        {
            IReadableStringCollection query = request.Query;
            if ((query != null) &amp;amp;&amp;amp; (query[&quot;X-Requested-With&quot;] == &quot;XMLHttpRequest&quot;))
            {
                return true;
            }
            IHeaderDictionary headers = request.Headers;
            return ((headers != null) &amp;amp;&amp;amp; (headers[&quot;X-Requested-With&quot;] == &quot;XMLHttpRequest&quot;));
        }

        // For more information on configuring authentication, please visit http://go.microsoft.com/fwlink/?LinkId=301864
        public void ConfigureAuth(IAppBuilder app)
        {
            // Enable the application to use a cookie to store information for the signed in user
            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                LoginPath = new PathString(&quot;/Account/Login&quot;),
                Provider = new CookieAuthenticationProvider
                {
                    OnApplyRedirect = ctx =&amp;gt;
                    {
                        if (!IsAjaxRequest(ctx.Request))
                        {
                            ctx.Response.Redirect(ctx.RedirectUri);
                        }
                    }
                }
            });
            // Use a cookie to temporarily store information about a user logging in with a third party login provider
            app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

        }
    }

&lt;/pre&gt;
Now our application behaves like it did before we upgraded to MVC 5.  I have updated the &lt;a href=&quot;https://simplesecurity.codeplex.com/SourceControl/latest&quot; target=&quot;_blank&quot;&gt;SimpleSecurity reference application&lt;/a&gt; with this modification. &amp;nbsp;If you prefer to handle this change in your client code you can just remove this modification.&lt;br /&gt;
&lt;br /&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
 SyntaxHighlighter.highlight();
&lt;/script&gt;</content><link rel='replies' type='application/atom+xml' href='http://kevin-junghans.blogspot.com/feeds/6067011232984348945/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kevin-junghans.blogspot.com/2013/12/returning-401-http-status-code-on.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2016746845209941562/posts/default/6067011232984348945'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2016746845209941562/posts/default/6067011232984348945'/><link rel='alternate' type='text/html' href='http://kevin-junghans.blogspot.com/2013/12/returning-401-http-status-code-on.html' title='Returning 401 HTTP Status Code on Authentication Failure in MVC 5 Web API&#39;s'/><author><name>Kevin Junghans</name><uri>http://www.blogger.com/profile/01125287678342544067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2016746845209941562.post-3660691656981415211</id><published>2013-11-08T09:04:00.000-05:00</published><updated>2018-07-26T15:02:12.366-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ASP.Net"/><category scheme="http://www.blogger.com/atom/ns#" term="ASP.NET Identity"/><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="MVC 5"/><category scheme="http://www.blogger.com/atom/ns#" term="security"/><category scheme="http://www.blogger.com/atom/ns#" term="SimpleSecurity"/><title type='text'>Decoupling ASP.NET Identify From Your MVC 5 Application</title><content type='html'>For many of the same &lt;a href=&quot;http://kevin-junghans.blogspot.com/2013/03/decoupling-simplemembership-from-your.html&quot;&gt;reasons I created class library that abstracts SimpleMembership&lt;/a&gt; I have created a class library for ASP.NET Identity. &amp;nbsp;I used the same interface I used in SimpleSecurity, which is basically the interface used by the class &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/webmatrix.webdata.websecurity(v=vs.111).aspx&quot; target=&quot;_blank&quot;&gt;WebSecurity &lt;/a&gt;in SimpleMembership. &amp;nbsp;The beauty of this approach is that I could take my old models, views, and controllers from an application that used SimpleMembership and now just plugin the new ASP.NET Identity. &amp;nbsp;The main difference is that anywhere that the user ID that uniquely defines a member is used it is now a string instead of an integer, because that is the default for ASP.NET Identity. There are methods to have it use an integer as well and I am debating incorporating that into this class library.&lt;br /&gt;
&lt;br /&gt;
All of the code for this is open source and available on the &lt;a href=&quot;https://github.com/kjunghans/SimpleSecurity&quot; target=&quot;_blank&quot;&gt;SimpleSecurity Project&lt;/a&gt;. &amp;nbsp;Just go to the&lt;a href=&quot;https://github.com/kjunghans/SimpleSecurity&quot; target=&quot;_blank&quot;&gt; Source Code page&lt;/a&gt; and download it. The class library is located in &lt;i&gt;AspNetIdentity\SimpleSecurity.AspNetIdentity&lt;/i&gt;. &amp;nbsp;The filters for authorization are located in &lt;i&gt;AspNetIdentity\SimpleSecurity.AspNetIdentity.Filters&lt;/i&gt; and there is a reference application in &lt;i&gt;AspNetIdentity\SimpleSecurity.AspNetIdentity.RefApp. &lt;/i&gt;The reference application demonstrates how to setup migrations, email confirmation during registration, password reset with a token, using basic authentication on Web API&#39;s, how to create an authorization attribute that uses ASP.NET Identity, and how to decouple your security model from your application model.&lt;br /&gt;
&lt;br /&gt;
To use this in a new project it will have to be an MVC 5 application. If you have an existing MVC 4 application there are instruction for&lt;a href=&quot;http://www.asp.net/mvc/tutorials/mvc-5/how-to-upgrade-an-aspnet-mvc-4-and-web-api-project-to-aspnet-mvc-5-and-web-api-2&quot; target=&quot;_blank&quot;&gt; upgrading to MVC 5 here&lt;/a&gt;. &amp;nbsp;You get the new MVC 5 assemblies with NuGet. You will also need to use NuGet to get the assemblies for OWIN and ASP.NET Identity. You can use the reference application to see exactly what assemblies are required. &amp;nbsp;You will also need to incorporate Startup.Auth.cs in your App_Start directory and Startup.cs in the root of your application. Again, use the reference application to get the content of these classes. &amp;nbsp;You will also need to configure the database initializer for migrations of SimpleSecurity database in your web.config.&lt;br /&gt;
&lt;br /&gt;
I hope this helps you get a jump start on using ASP.NET Identity. The lack of documentation is rather frustrating at this time and hopefully these examples will help. &amp;nbsp;I also think that using SimpleSecurity is a better approach to using ASP.NET Identity rather than the code that is generated by the T4 template that peppers your application code with Entity Framework and data storage details that should not be part of your application domain. &amp;nbsp;And since ASP.NET Identity is still in flux it gives you one class library to update rather than finding code scattered in your MVC application.&lt;br /&gt;
&lt;br /&gt;
As always, I am interested in ways to make SimpleSecurity better and I am interested in your comments. You can comment on this blog or on the &lt;a href=&quot;https://github.com/kjunghans/SimpleSecurity/issues&quot; target=&quot;_blank&quot;&gt;Issues &lt;/a&gt;page in the SimpleSecurity project.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://kevin-junghans.blogspot.com/feeds/3660691656981415211/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kevin-junghans.blogspot.com/2013/11/decoupling-aspnet-identify-from-your.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2016746845209941562/posts/default/3660691656981415211'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2016746845209941562/posts/default/3660691656981415211'/><link rel='alternate' type='text/html' href='http://kevin-junghans.blogspot.com/2013/11/decoupling-aspnet-identify-from-your.html' title='Decoupling ASP.NET Identify From Your MVC 5 Application'/><author><name>Kevin Junghans</name><uri>http://www.blogger.com/profile/01125287678342544067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2016746845209941562.post-1832474117666146178</id><published>2013-10-26T12:50:00.000-04:00</published><updated>2013-10-26T12:55:21.159-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ASP.Net"/><category scheme="http://www.blogger.com/atom/ns#" term="ASP.NET Identity"/><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="MVC 5"/><category scheme="http://www.blogger.com/atom/ns#" term="security"/><title type='text'>Adding Email Confirmation to ASP.NET Identity in MVC 5</title><content type='html'>In a previous article I demonstrated &lt;a href=&quot;http://kevin-junghans.blogspot.com/2013/10/customizing-aspnet-identity-in-mvc-5.html&quot; target=&quot;_blank&quot;&gt;how to customize the user profile information in ASP.NET Identity&lt;/a&gt;. &amp;nbsp;Specifically I showed how to add capturing an email address for the user. We will expand on this work and add email confirmation to the registration process. &amp;nbsp;This process will send an email to the user with a link they can click on to confirm their registration and log in to the system. Prior to confirmation they will not be able to log in. &amp;nbsp;This process will be similar to the one I described for &lt;a href=&quot;http://kevin-junghans.blogspot.com/2013/02/adding-email-confirmation-to.html&quot; target=&quot;_blank&quot;&gt;adding email confirmation to SimpleMembership&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
First we need to modify the user information to store a the confirmation token and a flag indicating whether confirmation was completed or not. &amp;nbsp;So now our &lt;i&gt;ApplicationUser&lt;/i&gt; looks like this.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;    public class ApplicationUser : IdentityUser
    {
        public string Email { get; set; }
        public string ConfirmationToken { get; set; }
        public bool IsConfirmed { get; set; }
    }
&lt;/pre&gt;
&lt;br /&gt;
If you have already made changes to the &lt;i&gt;ApplicationUser &lt;/i&gt;before you will need to &lt;a href=&quot;http://kevin-junghans.blogspot.com/2013/04/using-code-first-migration-with.html&quot; target=&quot;_blank&quot;&gt;enable migrations&lt;/a&gt;&amp;nbsp;and add a migration for these changes to take affect. &amp;nbsp;Now we can capture this information during the registration process and send the email.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;        private string CreateConfirmationToken()
        {
            return ShortGuid.NewGuid();
        }

        private void SendEmailConfirmation(string to, string username, string confirmationToken)
        {
            dynamic email = new Email(&quot;RegEmail&quot;);
            email.To = to;
            email.UserName = username;
            email.ConfirmationToken = confirmationToken;
            email.Send();
        }

        //
        // POST: /Account/Register
        [HttpPost]
        [AllowAnonymous]
        [ValidateAntiForgeryToken]
        public async Task&amp;lt;ActionResult&amp;gt; Register(RegisterViewModel model)
        {
            if (ModelState.IsValid)
            {
                string confirmationToken = CreateConfirmationToken();
                var user = new ApplicationUser()
                {
                    UserName = model.UserName,
                    Email = model.Email,
                    ConfirmationToken = confirmationToken, 
                        IsConfirmed = false };
                var result = await UserManager.CreateAsync(user, model.Password);
                if (result.Succeeded)
                {
                    SendEmailConfirmation(model.Email, model.UserName, confirmationToken);
                    return RedirectToAction(&quot;RegisterStepTwo&quot;, &quot;Account&quot;);
                }
                else
                {
                    AddErrors(result);
                }
            }

            // If we got this far, something failed, redisplay form
            return View(model);
        }

&lt;/pre&gt;
&lt;br /&gt;
To generate the token I use a class called &lt;i&gt;ShortGuid&lt;/i&gt; that takes a GUID and encodes it so that it is shorter and is URL safe.  I got the code for this class from &lt;a href=&quot;http://www.singular.co.nz/blog/archive/2007/12/20/shortguid-a-shorter-and-url-friendly-guid-in-c-sharp.aspx&quot; target=&quot;_blank&quot;&gt;this blog&lt;/a&gt;. &amp;nbsp;I add the generated token to the new user and set &lt;i&gt;IsConfirmed &lt;/i&gt;to false. Then I send the email. &amp;nbsp;I use &lt;a href=&quot;https://www.nuget.org/packages/postal/&quot; target=&quot;_blank&quot;&gt;Postal &lt;/a&gt;to generate the emails. &amp;nbsp;Postal uses the Razor engine to create your dynamic email content that can include content such as the user name and the custom URL with the confirmation token. &amp;nbsp;The redirect to the RegisterStepTwo action just displays a view to the user that tells them to look for the email to complete the registration process.&lt;br /&gt;
&lt;br /&gt;
Once the user gets the email they click on the link that will take us back to the controller action &lt;i&gt;RegisterConfirmation&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;        private bool ConfirmAccount(string confirmationToken)
        {
            ApplicationDbContext context = new ApplicationDbContext();
            ApplicationUser user =  context.Users.SingleOrDefault(u =&amp;gt; u.ConfirmationToken == confirmationToken);
            if (user != null)
            {
                user.IsConfirmed = true;
                DbSet&amp;lt;ApplicationUser&gt; dbSet = context.Set&amp;lt;ApplicationUser&gt;();
                dbSet.Attach(user);
                context.Entry(user).State = EntityState.Modified;
                context.SaveChanges();

                return true;
            }
            return false;
        }

        [AllowAnonymous]
        public ActionResult RegisterConfirmation(string Id)
        {
            if (ConfirmAccount(Id))
            {
                return RedirectToAction(&quot;ConfirmationSuccess&quot;);
            }
            return RedirectToAction(&quot;ConfirmationFailure&quot;);
        }
&lt;/pre&gt;
&lt;br /&gt;
The method &lt;i&gt;ConfirmAccount &lt;/i&gt;does a query to see if we can find a user with the confirmation token that was passed in the URL.  If we find a user we set &lt;i&gt;IsConfirmed &lt;/i&gt;to true and return true from the method; otherwise we return false. If the user is confirmed they will be able to log in.  To make sure that the user could not log in before confirmation we need to make a small change to the &lt;i&gt;Login &lt;/i&gt;action.
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;        [HttpPost]
        [AllowAnonymous]
        [ValidateAntiForgeryToken]
        public async Task&amp;lt;ActionResult&gt; Login(LoginViewModel model, string returnUrl)
        {
            if (ModelState.IsValid)
            {
                var user = await UserManager.FindAsync(model.UserName, model.Password);
                if (user != null &amp;amp;&amp;amp; user.IsConfirmed)
                {
                    await SignInAsync(user, model.RememberMe);
                    return RedirectToLocal(returnUrl);
                }
                else
                {
                    ModelState.AddModelError(&quot;&quot;, &quot;Invalid username or password.&quot;);
                }
            }

            // If we got this far, something failed, redisplay form
            return View(model);
        }
&lt;/pre&gt;
&lt;br /&gt;
All we do is check that if we find a user that the &lt;i&gt;IsConfirmed &lt;/i&gt;flag is set to true. &amp;nbsp;If it is false then we do not log the user in and generate an error message.&lt;br /&gt;
&lt;br /&gt;
That is all there is to setting up email confirmation using ASP.NET Identity in MVC 5. &amp;nbsp;You can get the source code for this example from the &lt;a href=&quot;https://simplesecurity.codeplex.com/SourceControl/latest&quot; target=&quot;_blank&quot;&gt;SimpleSecurity Project&lt;/a&gt;. You can find it in the AspNetIdentity folder.&lt;br /&gt;
&lt;br /&gt;
One observation is that I had to make low level EF calls using the &lt;i&gt;DbContext &lt;/i&gt;to make this work. &amp;nbsp;The &lt;i&gt;UserManager &lt;/i&gt;provided by ASP.NET Identity to encapsulate EF and provide access to &lt;i&gt;ApplicationUser &lt;/i&gt;did not provide me with enough control to do what I needed to accomplish. &amp;nbsp;It makes sense to me to add another layer on top of ASP.NET Identity that makes it easier to use and decouples it from the web application. &amp;nbsp;I &lt;a href=&quot;http://kevin-junghans.blogspot.com/2013/03/decoupling-simplemembership-from-your.html&quot; target=&quot;_blank&quot;&gt;decoupled SimpleMembership from the web application&lt;/a&gt; and it worked well. Look for something like this for ASP.NET Identity in the future that will be open source and available in the &lt;a href=&quot;https://simplesecurity.codeplex.com/&quot; target=&quot;_blank&quot;&gt;SimpleSecurity Project&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
 SyntaxHighlighter.highlight();
&lt;/script&gt;</content><link rel='replies' type='application/atom+xml' href='http://kevin-junghans.blogspot.com/feeds/1832474117666146178/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kevin-junghans.blogspot.com/2013/10/adding-email-confirmation-to-aspnet.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2016746845209941562/posts/default/1832474117666146178'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2016746845209941562/posts/default/1832474117666146178'/><link rel='alternate' type='text/html' href='http://kevin-junghans.blogspot.com/2013/10/adding-email-confirmation-to-aspnet.html' title='Adding Email Confirmation to ASP.NET Identity in MVC 5'/><author><name>Kevin Junghans</name><uri>http://www.blogger.com/profile/01125287678342544067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2016746845209941562.post-1911113266656939721</id><published>2013-10-25T11:33:00.000-04:00</published><updated>2013-10-25T11:35:45.629-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ASP.Net"/><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="MVC 5"/><category scheme="http://www.blogger.com/atom/ns#" term="SimpleMembership"/><category scheme="http://www.blogger.com/atom/ns#" term="SimpleSecurity"/><category scheme="http://www.blogger.com/atom/ns#" term="WebMatrix"/><title type='text'>Upgrading a Web Application Using SimpleMembership to ASP.NET MVC 5</title><content type='html'>I recently tried to upgrade the &lt;a href=&quot;https://simplesecurity.codeplex.com/&quot; target=&quot;_blank&quot;&gt;SimpleSecurity &lt;/a&gt;reference application from MVC 4 to MVC 5 and ran into some issues. &amp;nbsp;SimpleSecurity encapsulates and decouples SimpleMembership from your ASP.NET application and the underlying issue was compatibility with the WebMatrix assemblies that SimpleMembership uses and the new assemblies for MVC version 5, Web API version 5, and Razor version 3. &lt;br /&gt;
&lt;br /&gt;
I followed the &lt;a href=&quot;http://www.asp.net/mvc/tutorials/mvc-5/how-to-upgrade-an-aspnet-mvc-4-and-web-api-project-to-aspnet-mvc-5-and-web-api-2&quot; target=&quot;_blank&quot;&gt;instruction for upgrading to MVC 5 that are posted here&lt;/a&gt;&amp;nbsp;and received this error on application start.&lt;br /&gt;
&lt;i style=&quot;color: maroon; font-family: Verdana; font-size: 14pt;&quot;&gt;Attempt by security transparent method &#39;WebMatrix.WebData.PreApplicationStartCode.Start()&#39; to access security critical method &#39;System.Web.WebPages.Razor.WebPageRazorHost.AddGlobalImport(System.String)&#39; failed.&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
I did some research and found that others were having the same issue. Well it turns out I did not follow the instructions exactly. &amp;nbsp;Here is one note in the instructions I did not pay close attention to.&lt;br /&gt;
&lt;br /&gt;
&lt;strong style=&quot;border: 0px; color: #222222; font-family: &#39;Segoe UI&#39;, Tahoma, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 18.203125px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;Note:&amp;nbsp;&lt;/strong&gt;&lt;span style=&quot;color: #222222; font-family: &#39;Segoe UI&#39;, Tahoma, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 18.203125px;&quot;&gt;Microsoft-Web-Helpers has been replaced&amp;nbsp; with Microsoft.AspNet.WebHelpers. You should remove the old package first,&amp;nbsp; and then install the newer package.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
I opened up the NuGet Package Manager and installed the package&amp;nbsp;Microsoft.AspNet.WebHelpers and things started to work. &amp;nbsp;Note that when you create a new MVC 5 application and try to incorporate SimpleSecurity or SimpleMembership you will hit the same issue because Microsoft.AspNet.WebHelpers &amp;nbsp;is not installed by default. &amp;nbsp;It has to be present for SimpleMembership to run correctly.&lt;br /&gt;
&lt;br /&gt;
I verified that all of the features in the reference application are working correctly after the upgrade. &amp;nbsp;Even the generation of the emails using Postal worked, which I was not sure of because of the upgrade of Razor as well. &lt;br /&gt;
&lt;br /&gt;
One change I needed to make to the SimpleSecurity assembly was to remove the filters &lt;i&gt;AuthorizeAttribute &lt;/i&gt;and &lt;i&gt;BasicAuthorizeAttribute &lt;/i&gt;and put them in a separate assembly. &amp;nbsp;I did this because they are dependent upon MVC and Web API assemblies. &amp;nbsp;So now there is a version for MVC 4 and another for MVC 5.&lt;br /&gt;
&lt;br /&gt;
You can get the source code for the MVC 5 version of the Reference Application from the &lt;a href=&quot;https://simplesecurity.codeplex.com/SourceControl/latest&quot; target=&quot;_blank&quot;&gt;SimpleSecurity Project Source Code&lt;/a&gt; page. You will find it under SimpleSecurityMVC5\SeedSimpleUpgradeTo5.</content><link rel='replies' type='application/atom+xml' href='http://kevin-junghans.blogspot.com/feeds/1911113266656939721/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kevin-junghans.blogspot.com/2013/10/upgrading-web-application-using.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2016746845209941562/posts/default/1911113266656939721'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2016746845209941562/posts/default/1911113266656939721'/><link rel='alternate' type='text/html' href='http://kevin-junghans.blogspot.com/2013/10/upgrading-web-application-using.html' title='Upgrading a Web Application Using SimpleMembership to ASP.NET MVC 5'/><author><name>Kevin Junghans</name><uri>http://www.blogger.com/profile/01125287678342544067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2016746845209941562.post-1287698329114442759</id><published>2013-10-21T15:40:00.000-04:00</published><updated>2014-02-13T10:20:46.620-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ASP.Net"/><category scheme="http://www.blogger.com/atom/ns#" term="ASP.NET Identity"/><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="MVC 5"/><category scheme="http://www.blogger.com/atom/ns#" term="SimpleMembership"/><title type='text'>Customizing ASP.NET Identity in MVC 5</title><content type='html'>For those of you that follow my Blog you know that one of the subjects I write a lot about is customizing SimpleMembership for ASP.NET security in web applications and some of you have been asking if I have tried using it with Visual Studio 2013 RC or Preview. &amp;nbsp;Recently I have taken the time to explore using SimpleSecurity and SimpleMembership with VS 2013 RC and more recently the final release now available to MSDN Subscribers. &amp;nbsp; The short of it is there are problems with upgrading to MVC 5, &amp;nbsp;which was released to coincide with VS 2013, as described in this &lt;a href=&quot;http://stackoverflow.com/questions/19169846/is-asp-net-mvc-5-incompatible-with-the-webmatrix-simplemembershipprovider/19272452#19272452&quot; target=&quot;_blank&quot;&gt;StackOverflow QA&lt;/a&gt;. &amp;nbsp;You can still develop your MVC 4 applications in VS 2013 but you will miss out on some of the new features available in MVC 5 and Razor 3.&lt;br /&gt;
&lt;br /&gt;
The other problem is that SimpleMembership is going away in MVC 5 as the provider for ASP.NET security. &amp;nbsp;Microsoft has gone to another membership provider called &lt;a href=&quot;http://blogs.msdn.com/b/webdev/archive/2013/06/27/introducing-asp-net-identity-membership-system-for-asp-net-applications.aspx&quot; target=&quot;_blank&quot;&gt;ASP.NET Identity&lt;/a&gt;. In this article I will start looking at how to customize ASP.NET Identity and contrast that with using SimpleMembership. &amp;nbsp;There are a number of new features and benefits in ASP.NET Identity that you can &lt;a href=&quot;http://blogs.msdn.com/b/webdev/archive/2013/06/27/introducing-asp-net-identity-membership-system-for-asp-net-applications.aspx&quot; target=&quot;_blank&quot;&gt;read about here&lt;/a&gt;. &amp;nbsp;The benefits and the fact that this is the chosen direction for ASP.NET security make a compelling reason to look into using this going forward.&lt;br /&gt;
&lt;br /&gt;
It turns out that it is quite simple to customize the user profile in ASP.NET Identity. &amp;nbsp;First I started by creating a new MVC 5 application. &amp;nbsp;You no longer select whether you want an Internet or Intranet application, you just select the MVC template and select the authentication type you want to use. For an Internet type application you select &lt;b&gt;Individual User Accounts&lt;/b&gt;. &amp;nbsp;Once your web application is created open IdentityModels.cs in the Models directory. &amp;nbsp;You will see a class called &lt;i&gt;ApplicationUser &lt;/i&gt;which is analogues to the &lt;i&gt;UserProfile &lt;/i&gt;in SimpleMembership. &amp;nbsp;It is an empty class that inherits from &lt;i&gt;IdentityUser &lt;/i&gt;which has these properties.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;    public class IdentityUser : IUser
    {
        public IdentityUser();
        public IdentityUser(string userName);

        public virtual ICollection&amp;lt;identityuserclaim&amp;gt; Claims { get; }
        public virtual string Id { get; set; }
        public virtual ICollection&amp;lt;identityuserlogin&amp;gt; Logins { get; }
        public virtual string PasswordHash { get; set; }
        public virtual ICollection&amp;lt;identityuserrole&amp;gt; Roles { get; }
        public virtual string SecurityStamp { get; set; }
        public virtual string UserName { get; set; }
    }
&lt;/pre&gt;
&lt;br /&gt;
What you will notice from this implementation is that the Id is no longer an integer as it was SimpleMembership. It now uses a string which the default implementation stuffs with a GUID.  In this example I will just add an email address to the user so we can look at adding email confirmation in a later article. Here is what it looks like.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;    public class ApplicationUser : IdentityUser
    {
        public string Email { get; set; }
    }
&lt;/pre&gt;
&lt;br /&gt;
Now to allow the user to enter their email address during registration I first update the registration model.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;    public class RegisterViewModel
    {
        [Required]
        [Display(Name = &quot;User name&quot;)]
        public string UserName { get; set; }

        [Required]
        [StringLength(100, ErrorMessage = &quot;The {0} must be at least {2} characters long.&quot;, MinimumLength = 6)]
        [DataType(DataType.Password)]
        [Display(Name = &quot;Password&quot;)]
        public string Password { get; set; }

        [DataType(DataType.Password)]
        [Display(Name = &quot;Confirm password&quot;)]
        [Compare(&quot;Password&quot;, ErrorMessage = &quot;The password and confirmation password do not match.&quot;)]
        public string ConfirmPassword { get; set; }

        [Required]
        [Display(Name = &quot;Email address&quot;)]
        public string Email { get; set; }

    }
&lt;/pre&gt;
&lt;br /&gt;
And then I update the View to include a label and text box for the email.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: html&quot;&gt;   &amp;lt;div class=&quot;form-group&quot;&amp;gt;
        @Html.LabelFor(m =&amp;gt; m.Email, new { @class = &quot;col-md-2 control-label&quot; })
        &amp;lt;div class=&quot;col-md-10&quot;&amp;gt;
            @Html.TextBoxFor(m =&amp;gt; m.Email, new { @class = &quot;form-control&quot; })
        &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
&lt;/pre&gt;
&lt;br /&gt;
To test this out I changed the About page to display the current users email.  This also shows how we can access user information in the application.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;    public ActionResult About()
    {
        ViewBag.Message = &quot;Your application description page.&quot;;
        UserManager&amp;lt;ApplicationUser&amp;gt; UserManager = new UserManager&amp;lt;ApplicationUser&amp;gt;(new UserStore&amp;lt;ApplicationUser&amp;gt;(new ApplicationDbContext()));         
        var user = UserManager.FindById(User.Identity.GetUserId());
        if (user != null)
            ViewBag.Email = user.Email;
        else
            ViewBag.Email = &quot;User not found.&quot;;

        return View();
    }
&lt;/pre&gt;
&lt;br /&gt;
That is all there is to customizing the user information you can store when using ASP.NET Identity. &amp;nbsp;In a future article I will look at how we can add email confirmation to ASP.NET Identity.&lt;br /&gt;
&lt;br /&gt;
Also follow this Blog for future updates as I continue to investigate if you can upgrade an existing MVC 4 application with SimpleMembership to MVC 5. It would be nice to migrate an existing application to MVC 5 without throwing away your whole security model and database.&lt;br /&gt;
&lt;br /&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
 SyntaxHighlighter.highlight();
&lt;/script&gt;</content><link rel='replies' type='application/atom+xml' href='http://kevin-junghans.blogspot.com/feeds/1287698329114442759/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kevin-junghans.blogspot.com/2013/10/customizing-aspnet-identity-in-mvc-5.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2016746845209941562/posts/default/1287698329114442759'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2016746845209941562/posts/default/1287698329114442759'/><link rel='alternate' type='text/html' href='http://kevin-junghans.blogspot.com/2013/10/customizing-aspnet-identity-in-mvc-5.html' title='Customizing ASP.NET Identity in MVC 5'/><author><name>Kevin Junghans</name><uri>http://www.blogger.com/profile/01125287678342544067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2016746845209941562.post-4562329703262010195</id><published>2013-10-01T09:17:00.000-04:00</published><updated>2013-10-01T09:17:08.001-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ASP.Net"/><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="MVC 4"/><category scheme="http://www.blogger.com/atom/ns#" term="security"/><category scheme="http://www.blogger.com/atom/ns#" term="SimpleMembership"/><title type='text'>Improving Performance of SimpleMembership By Using Claims-Based Access Control</title><content type='html'>Claims-based identity and access control became first class citizens with the introduction of .NET version 4.5. &amp;nbsp;This along with integrating Windows Identify Foundation (WIF) has added some very powerful security features to .NET 4.5. &amp;nbsp;In this article I will look how we can make a simple changes to SimpleSecurity to make it more efficient and reduce the number of times we need to hit the database during authorization by retrieving some of the information we need from claims. If you are not familiar with claims there is a&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ff359101.aspx&quot; target=&quot;_blank&quot;&gt; good introduction here&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
I originally introduced the idea of &amp;nbsp;decoupling the security model from the application by creating a custom &lt;i&gt;AuthorizeAttribute &lt;/i&gt;that accepted a resource and operation instead of a role. You can read more about it &lt;a href=&quot;http://kevin-junghans.blogspot.com/2013/08/decoupling-you-security-model-from.html&quot; target=&quot;_blank&quot;&gt;here &lt;/a&gt;and some later improvements &lt;a href=&quot;http://kevin-junghans.blogspot.com/2013/09/decoupling-your-security-model-revisited.html&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;. &amp;nbsp;In these designs I override the &lt;i&gt;OnAuthorization &lt;/i&gt;method and it looked like this.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;   public override void OnAuthorization(AuthorizationContext actionContext)
   {
       base.Roles = ResourceService.GetRolesAsCsv(_resourceId, _operation);
       base.OnAuthorization(actionContext);
   }
&lt;/pre&gt;
&lt;br /&gt;
This was implemented by getting a list of roles as a comma separated string that was added to the base &lt;i&gt;Roles &lt;/i&gt;property and then called the base &lt;i&gt;OnAuthorization &lt;/i&gt;method to complete the authorization process. Pretty straight forward. The problem I found is that calling the base &lt;i&gt;OnAuthorization &lt;/i&gt;method requires two database calls; one to get the user ID from the user name of the current principal and then look up in the &lt;i&gt;webpages_UsersInRoles&lt;/i&gt; table and the joined&lt;i&gt; webpages_Roles&lt;/i&gt; table to see if there is a match with the list of roles provided to the &lt;i&gt;OnAuthorization &lt;/i&gt;method.&lt;br /&gt;
&lt;br /&gt;
It turns out that is completely unnecessary because the claims in the current principal already contain the roles for the user. &amp;nbsp;And this information is persisted in the authentication cookie so that it does not have to hit the database for every HTTP request. &amp;nbsp;So how do we take advantage of this. &amp;nbsp;First of all in our custom &lt;i&gt;AuthorizeAttribute &lt;/i&gt;we override the&amp;nbsp;&lt;i&gt;AuthorizeCore &lt;/i&gt;method instead of the &lt;i&gt;OnAuthorization &lt;/i&gt;method. It looks like this:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;protected override bool AuthorizeCore(HttpContextBase httpContext)
{
    //Get the current claims principal
    var prinicpal = (ClaimsPrincipal)Thread.CurrentPrincipal;
    //Make sure they are authenticated
    if (!prinicpal.Identity.IsAuthenticated)
        return false;
    //Get the roles from the claims
    var roles = prinicpal.Claims.Where(c =&amp;gt; c.Type == ClaimTypes.Role).Select(c =&amp;gt; c.Value).ToArray();
    //Check if they are authorized
    return ResourceService.Authorize(_resourceId, _operation, roles);
}
&lt;/pre&gt;
&lt;br /&gt;
The steps are described in the comments. First we get the &lt;i&gt;ClaimsPrincipal &lt;/i&gt;of the current user. &amp;nbsp;Then we check to make sure they are authenticated. If they are not then we just return false and the authorization will fail. &amp;nbsp;Next we query the claims using LINQ to get a string array of roles. &amp;nbsp;This is then passed to a method to see if we have can match any of the user&#39;s roles to roles assigned to the resource/operation. &amp;nbsp;If there is a match it returns true, if not it returns false. &amp;nbsp;We still have to do a database look-up to get the roles assigned to the resource/operation, but we have eliminated several queries to get the users roles.&lt;br /&gt;
&lt;br /&gt;
Now you might be thinking, why don&#39;t we put the roles for all of the resources and operations in the claims also. &amp;nbsp;It turns out that .NET 4.5 makes it easy to put additional claim information into the current principal and even handles breaking the information into multiple cookies if it gets too large. &amp;nbsp;But that is a topic for a future article. &amp;nbsp;Adding this information to the claims would depend on the application and the number of resources, operations, and roles used. &amp;nbsp;We do not want to make the cookie too large and pass it around all of the time. &lt;br /&gt;
&lt;br /&gt;
I will tackle adding more claims in another article because there is other useful information we can add to the claims. &amp;nbsp;For example, the user ID, which is the foreign key in a lot of other databases/tables for tying user information to other information in the system. &amp;nbsp;Usually when you want to query information based on the current user you get the user name from the principal, do a database query to get the user ID, and then query for the information we a looking for. We can eliminate this intermediate step by putting the user ID in the claims.&lt;br /&gt;
&lt;br /&gt;
You can get the source code and example application from the &lt;a href=&quot;https://simplesecurity.codeplex.com/&quot; target=&quot;_blank&quot;&gt;SimpleSecurity Project on CodePlex&lt;/a&gt;. Just go to the &lt;a href=&quot;https://simplesecurity.codeplex.com/SourceControl/latest&quot; target=&quot;_blank&quot;&gt;Source Code&lt;/a&gt; tab and select the download link.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
 SyntaxHighlighter.highlight();
&lt;/script&gt;</content><link rel='replies' type='application/atom+xml' href='http://kevin-junghans.blogspot.com/feeds/4562329703262010195/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kevin-junghans.blogspot.com/2013/10/improving-performance-of.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2016746845209941562/posts/default/4562329703262010195'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2016746845209941562/posts/default/4562329703262010195'/><link rel='alternate' type='text/html' href='http://kevin-junghans.blogspot.com/2013/10/improving-performance-of.html' title='Improving Performance of SimpleMembership By Using Claims-Based Access Control'/><author><name>Kevin Junghans</name><uri>http://www.blogger.com/profile/01125287678342544067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2016746845209941562.post-8703632784061039402</id><published>2013-09-30T11:48:00.002-04:00</published><updated>2013-09-30T11:49:45.929-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ASP.Net"/><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="MVC 4"/><category scheme="http://www.blogger.com/atom/ns#" term="security"/><category scheme="http://www.blogger.com/atom/ns#" term="SimpleMembership"/><title type='text'>Decoupling Your Security Model Revisited</title><content type='html'>I while back I wrote an article &quot;&lt;a href=&quot;http://kevin-junghans.blogspot.com/2013/08/decoupling-you-security-model-from.html&quot; target=&quot;_blank&quot;&gt;Decoupling You Security Model From The Application Model With SimpleMembership&lt;/a&gt;&quot;. &amp;nbsp;In this article I proposed a design change to how the &lt;i&gt;AuthorizeAttribute &lt;/i&gt;is used that provides a decoupled security model that is more flexible as your ASP.NET MVC application evolves. &amp;nbsp;One reader provided good comments on what he did not like about the design, with one major issues being the use of magic strings to define the resources and operations that we are authorizing against. &amp;nbsp;If you recall from the previous article we define the custom &lt;i&gt;AuthorizeAttribute &lt;/i&gt;like this.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;    [SimpleAuthorize(Resource = &quot;UserProfile&quot;, Operation = &quot;modify&quot;)]
    public ActionResult ModifyUserProfile()
    {
        ViewBag.Message = &quot;Modify Your Profile&quot;;
        return View();
    }
&lt;/pre&gt;
&lt;br /&gt;
This is a valid concern so I revisited this design and came up with a solution that eliminates magic strings and will actually perform better.  Here is what our &lt;i&gt;SimpleAuthorize &lt;/i&gt;looks like now.
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;    [SimpleAuthorize(AppResources.UserProfile, Operations.Update)]
    public ActionResult ModifyUserProfile()
    {
        ViewBag.Message = &quot;Modify Your Profile&quot;;
        return View();
    }
&lt;/pre&gt;
&lt;br /&gt;
In the old design there was an &lt;i&gt;Operations &lt;/i&gt;table that contained all of the operations for each resource. This normalized design was very flexible and allowed for unlimited operations per resource. But in reality there are usually just a few operations used and they are mostly for your CRUD operations. In the new design I eliminated the &lt;i&gt;Operations &lt;/i&gt;table and added them directly to the Resource table as an enumerated type. &amp;nbsp;Here is how I defined my &lt;i&gt;Operations&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;    [Flags]
    public enum Operations : int
    {
        None = 0,
        Create = 1,
        Read = 2,
        Update = 4,
        Delete = 8,
        Execute = 16,
        All = 31
    }
&lt;/pre&gt;
&lt;br /&gt;
Notice that I have defined this &lt;i&gt;enum &lt;/i&gt;as &lt;i&gt;Flags&lt;/i&gt;.  This allows me to store any combination of operations in this enumerated type using bit operations. I can also use the&amp;nbsp;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.enum.hasflag.aspx&quot; target=&quot;_blank&quot;&gt;Enum.HasFlag&lt;/a&gt; method to see if an individual operation is in an instance of the &lt;i&gt;enum&lt;/i&gt;. &amp;nbsp;I added the types &lt;i&gt;None &lt;/i&gt;and &lt;i&gt;All &lt;/i&gt;for ease of initialization; they are not considered valid operations.&lt;br /&gt;
&lt;br /&gt;
I also changed the identifier for the Resource table to not be generated by the database. &amp;nbsp;This way the developer can use an enumerated type or static object with constants to define the resources available in their application. Here is how the I initialized the resources and operations in the Seed method of the database initializer used in the &lt;i&gt;SeedSimple &lt;/i&gt;example application.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;    //Build the operations available for this resource
    Operations operations = Operations.Read;
    operations |= Operations.Create;
    //Add the resource
    ResourceService.AddResource(AppResources.Foo, &quot;Foo&quot;, operations);
    //Map the resource/operation to the roles
    ResourceService.MapOperationToRole(AppResources.Foo, Operations.Read, &quot;User&quot;);
    ResourceService.MapOperationToRole(AppResources.Foo, Operations.Create, &quot;Admin&quot;);
&lt;/pre&gt;
&lt;br /&gt;
Unfortunately we still have to use magic strings for the roles because Microsoft designed it that way. &amp;nbsp;Besides eliminating the magic strings for &lt;i&gt;SimpleAuthorize &lt;/i&gt;filter this design will perform better because we do not have to join the &lt;i&gt;Resource &lt;/i&gt;and &lt;i&gt;Operations &lt;/i&gt;tables and we are performing look-ups on integers instead of strings.&lt;br /&gt;
&lt;br /&gt;
As always you can get this code from the &lt;a href=&quot;https://simplesecurity.codeplex.com/&quot; target=&quot;_blank&quot;&gt;SimpleSecurity Project on CodePlex&lt;/a&gt; to look into more of the details and play around with the code. &amp;nbsp;Let me know what your thoughts are in the comments on whether this is a better design or not.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
 SyntaxHighlighter.highlight();
&lt;/script&gt;</content><link rel='replies' type='application/atom+xml' href='http://kevin-junghans.blogspot.com/feeds/8703632784061039402/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kevin-junghans.blogspot.com/2013/09/decoupling-your-security-model-revisited.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2016746845209941562/posts/default/8703632784061039402'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2016746845209941562/posts/default/8703632784061039402'/><link rel='alternate' type='text/html' href='http://kevin-junghans.blogspot.com/2013/09/decoupling-your-security-model-revisited.html' title='Decoupling Your Security Model Revisited'/><author><name>Kevin Junghans</name><uri>http://www.blogger.com/profile/01125287678342544067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2016746845209941562.post-8016160908752596087</id><published>2013-09-13T09:23:00.001-04:00</published><updated>2013-09-13T09:23:56.279-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="IVR"/><category scheme="http://www.blogger.com/atom/ns#" term="MVC 4"/><category scheme="http://www.blogger.com/atom/ns#" term="Tropo"/><category scheme="http://www.blogger.com/atom/ns#" term="VoiceModel"/><category scheme="http://www.blogger.com/atom/ns#" term="VoiceXML"/><category scheme="http://www.blogger.com/atom/ns#" term="Voxeo"/><title type='text'>Multiple Recordings and Copying Recordings in VoiceModel</title><content type='html'>I had a couple of &lt;a href=&quot;http://voicemodel.codeplex.com/workitem/list/basic&quot; target=&quot;_blank&quot;&gt;enhancement requests&lt;/a&gt; in the &lt;a href=&quot;http://voicemodel.codeplex.com/&quot; target=&quot;_blank&quot;&gt;VoiceModel Project&lt;/a&gt; around making user recordings. &amp;nbsp;The &lt;a href=&quot;http://voicemodel.codeplex.com/workitem/1067&quot; target=&quot;_blank&quot;&gt;first request &lt;/a&gt;was to allow the directory that holds the recordings to be specified as a file structure or file share. And the &lt;a href=&quot;http://voicemodel.codeplex.com/workitem/1066&quot; target=&quot;_blank&quot;&gt;second request&lt;/a&gt; was to allow multiple recordings in a single session. &amp;nbsp;I finally got some time to look at implementing these enhancements and was pleasantly surprised that the features were already in place because of the flexibility in the VoiceModel architecture and state machine. Well, for the most part. I will explain one little change I had to make to VoiceModel to get this to work.&lt;br /&gt;
&lt;br /&gt;
To test this out I updated the &lt;i&gt;RecordingExample &lt;/i&gt;project in the &lt;i&gt;VMWithExamples &lt;/i&gt;solution. You can &lt;a href=&quot;https://voicemodel.codeplex.com/SourceControl/latest&quot; target=&quot;_blank&quot;&gt;get the source code here&lt;/a&gt;. Basically my solution was to add an On-Exit-Action to the recording state that copies the recorded file to another location. &amp;nbsp;This satisfies the request to be able to put recording in another location, including a file share. &amp;nbsp; Here is what the On-Exit-Action looks like.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;flow.AddState(ViewStateBuilder.Build(&quot;getRecording&quot;, &quot;playback&quot;,
    new Record(&quot;getRecording&quot;, &quot;Please record your information after the beep.  Press the pound key when you are finished.&quot;))
    .AddOnExitAction(delegate(CallFlow cf, State state, Event e)
    {
        VoiceModel.Logger.ILoggerService logger = VoiceModel.Logger.LoggerFactory.GetInstance();
        try
        {
            //Copy last recording to another location
            string recordingPhysicalPath = Server.MapPath(RecordingPath);
            string recordingFileName = recordingPhysicalPath + &quot;//&quot; + cf.SessionId + &quot;.wav&quot;;
            logger.Debug(&quot;Copying recording &quot; + recordingFileName);
            System.IO.File.Copy(recordingFileName, &quot;c://tmp//&quot; + cf.SessionId + &quot;_first.wav&quot;);
        }
        catch (Exception ex)
        {
            logger.Error(&quot;Error copying recording: &quot; + ex.Message);
        }
    }), true);

&lt;/pre&gt;
&lt;br /&gt;
That is all that is required to copy your recording to any location and even rename them. You will notice that I kept the session ID in the name to make sure the file name was unique and would not be copied over by another call into the system. You can use any scheme you would like to manage these file. For example, maybe you collected a unique caller identifier earlier in the voice application that you could use to organize recordings by caller.&lt;br /&gt;
&lt;br /&gt;
It turns out this helps satisfy the second requirement for multiple recordings. Since we can copy the recording to another location for safe keeping we can just add another &lt;i&gt;Record &lt;/i&gt;object in the application and it will replace the original recording. Then you just copy it again to another location using a different file name. I tested this out in the example and it works fine. The first recording I named &lt;i&gt;[SessionId]_first.wav&lt;/i&gt; and the second recording I named &lt;i&gt;[SessionId]_second.wav&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
But I did find a problem on playback of the recordings. &amp;nbsp;The URI for audio recording for the first and second recordings are the same since the file name is solely base on the session ID. &amp;nbsp;I used &lt;a href=&quot;http://evolution.voxeo.com/&quot; target=&quot;_blank&quot;&gt;Voxeo Cloud VoiceXML Platform &lt;/a&gt;to test this and it does an excellent job of caching audio files which I did not want in this case. &amp;nbsp;This caused the application to voice back the first recording when the caller should have been listening to the second recording. &amp;nbsp;I solved this by changing VoiceModel to specify not the use cache in the HTML header when retrieving audio recordings. You can get the latest release of &amp;nbsp;VoiceModel with this fix on &lt;a href=&quot;https://www.nuget.org/packages/VoiceModel/&quot; target=&quot;_blank&quot;&gt;NuGet&lt;/a&gt;. &amp;nbsp;This would have also been an issue if you &amp;nbsp;are setting up something like a voice mail system with VoiceModel, where you give the caller a chance to re-record what they have already recorded. &amp;nbsp;Playback would always just used the first recording.&lt;br /&gt;
&lt;br /&gt;
This example also demonstrates how easy it is to add logging to your VoiceModel applications. This proved invaluable when troubleshooting initial issues when trying to copy recordings. &amp;nbsp;The only other thing you need to do to add this logging is make sure you have a log4net config file in the root of your application directory.&lt;br /&gt;
&lt;br /&gt;
I love it when enhancement requests can be handled with very little change to the code.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
 SyntaxHighlighter.highlight();
&lt;/script&gt;</content><link rel='replies' type='application/atom+xml' href='http://kevin-junghans.blogspot.com/feeds/8016160908752596087/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kevin-junghans.blogspot.com/2013/09/multiple-recordings-and-copying.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2016746845209941562/posts/default/8016160908752596087'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2016746845209941562/posts/default/8016160908752596087'/><link rel='alternate' type='text/html' href='http://kevin-junghans.blogspot.com/2013/09/multiple-recordings-and-copying.html' title='Multiple Recordings and Copying Recordings in VoiceModel'/><author><name>Kevin Junghans</name><uri>http://www.blogger.com/profile/01125287678342544067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2016746845209941562.post-171141705868811349</id><published>2013-08-08T11:19:00.000-04:00</published><updated>2013-08-08T11:19:17.361-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="AJAX"/><category scheme="http://www.blogger.com/atom/ns#" term="ASP.Net"/><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="MVC 4"/><category scheme="http://www.blogger.com/atom/ns#" term="security"/><category scheme="http://www.blogger.com/atom/ns#" term="Web API"/><category scheme="http://www.blogger.com/atom/ns#" term="WIF"/><title type='text'>SessionAuthenticationModule Causes Strange Redirect Behavior</title><content type='html'>I was working on a web project using ASP.NET MVC 4 when I started seeing some strange behavior. Some of my AJAX calls to ASP.NET Web API services were getting redirected back to the same URL. The only difference between the original URL used to make the call and the redirected URL was changes in case sensitivity. While this could just be annoying and cause some performance issues this was causing my application real issues because the redirected web request was missing some header information. &amp;nbsp;Specifically I was using &lt;a href=&quot;http://kevin-junghans.blogspot.com/2013/02/mixing-forms-authentication-basic.html&quot;&gt;basic authentication on the calls to the Web API&#39;s&lt;/a&gt;&amp;nbsp;and the header was missing the authentication information and therefore this was causing the requests to fail authentication/authorization. &amp;nbsp;For the life of me I could not figure out what was causing the redirects.&lt;br /&gt;
&lt;br /&gt;
Then I started thinking back to what had changed in the application that may have introduced this behavior. &amp;nbsp;I had added the use of the &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/microsoft.identitymodel.web.sessionauthenticationmodule.aspx&quot;&gt;&lt;i&gt;SessionAuthenticationModule &lt;/i&gt;&lt;/a&gt;so that I could store claim information in cookies. This allowed me to keep important information in the claim principal without having to transform it on every request and therefore hitting my back-end database every time. &amp;nbsp;You can read about adding this valuable feature to your web application in this &lt;a href=&quot;http://leastprivilege.com/2012/02/09/replacing-asp-net-forms-authentication-with-wif-session-authentication-for-the-better/&quot;&gt;great article by Dominick Baier&lt;/a&gt;. &amp;nbsp;If you have access to PluralSight I would also recommend viewing Dominick&#39;s training course&amp;nbsp;&lt;a href=&quot;http://pluralsight.com/training/courses/TableOfContents?courseName=iac-aspnet&amp;amp;highlight=dominick-baier_iac-aspnet-m5-transformationsessions*8#iac-aspnet-m5-transformationsessions&quot; target=&quot;_blank&quot;&gt;Identity and Access Control in ASP.NET 4.5&lt;/a&gt; which also covers this topic in great detail.&lt;br /&gt;
&lt;br /&gt;
So to find a solution I Googled &lt;i&gt;SessionAuthenticationModule &lt;/i&gt;and &lt;i&gt;redirect &lt;/i&gt;and came across &lt;a href=&quot;http://brockallen.com/2013/02/08/beware-wif-session-authentication-module-sam-redirects-and-webapi-services-in-the-same-application/&quot; target=&quot;_blank&quot;&gt;this article&lt;/a&gt; that described my problem to a tee. Apparently this is a known behavior of using the &lt;i&gt;SessionAuthenticationModule&lt;/i&gt;. &amp;nbsp;If you use this module and you use the wrong case for the URL it will redirect back to the same URL using the proper case. And as I pointed out it will leave some header information out of the new web request. &amp;nbsp;Why they worried about case sensitivity when IIS does not is beyond my comprehension.&lt;br /&gt;
&lt;br /&gt;
So the solution was to fix the case of any URLS in any AJAX calls and any client requests for server resources to match what the web application uses. &amp;nbsp;Problem solved. I thought this experience was worth repeating since finding this obscure issue can be hard to troubleshoot.</content><link rel='replies' type='application/atom+xml' href='http://kevin-junghans.blogspot.com/feeds/171141705868811349/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kevin-junghans.blogspot.com/2013/08/sessionauthenticationmodule-causes.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2016746845209941562/posts/default/171141705868811349'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2016746845209941562/posts/default/171141705868811349'/><link rel='alternate' type='text/html' href='http://kevin-junghans.blogspot.com/2013/08/sessionauthenticationmodule-causes.html' title='SessionAuthenticationModule Causes Strange Redirect Behavior'/><author><name>Kevin Junghans</name><uri>http://www.blogger.com/profile/01125287678342544067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2016746845209941562.post-8410338906705712239</id><published>2013-08-03T11:44:00.000-04:00</published><updated>2018-07-26T14:57:48.253-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ASP.Net"/><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="MVC 4"/><category scheme="http://www.blogger.com/atom/ns#" term="SimpleMembership"/><title type='text'>Decoupling You Security Model From The Application Model With SimpleMembership</title><content type='html'>One of the peeves I have with ASP.NET MVC and &amp;nbsp;how security is handled is that you have to design your security model up front while you are designing your web application. &amp;nbsp;You have to determine which roles you need to have while implementing your application so that you can add them to the &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.web.mvc.authorizeattribute(v=vs.108).aspx&quot;&gt;&lt;i&gt;Authorize &lt;/i&gt;&lt;/a&gt;attribute on the controllers actions. &amp;nbsp;Here is an example of how you control access to controller actions.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;   [Authorize(Roles = &quot;admin,user&quot;)]
    public ActionResult DoSomething()
    {
        ViewBag.Message = &quot;Do something really spectacular.&quot;;
        return View();
    }
&lt;/pre&gt;
&lt;br /&gt;
Now when we want to change our security model, such as adding new roles, we have to go through the whole application changing these &lt;i&gt;Authorize&lt;/i&gt; attributes, recompile the application, and redeploy.  This coupling causes a lot of inefficiencies.
&lt;br /&gt;
&lt;br /&gt;
But you can customize &lt;i&gt;SimpleMembership &lt;/i&gt;to handle this in a better way that decouples the security model form your application domain.  I will demonstrate how to do this based on the work that has already been started on customizing &lt;i&gt;SimpleMembership &lt;/i&gt;in the &lt;a href=&quot;https://github.com/kjunghans/SimpleSecurity&quot;&gt;SimpleSecurity project&lt;/a&gt;. This is an open source project you can find on GitHub which demonstrates methods to enhance &lt;i&gt;SimpleMembership&lt;/i&gt;. The design of this enhancement is to use a customized &lt;i&gt;Authorize&lt;/i&gt; attribute that does not take roles as parameters; instead it uses a resource parameter and an operation parameter. A resource is an abstract representation of an item in your application domain. An operation is an action you are going to perform on that resource, such as read, write or modify.  An example might be that you have a web application that lets a user modify their profile. In this case you could label the resource as &quot;UserProfile&quot; and the operation would be &quot;modify&quot;.  Here is an example of what our new Authorize attribute will look like.
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;    [SimpleAuthorize(Resource = &quot;UserProfile&quot;, Operation = &quot;modify&quot;)]
    public ActionResult ModifyUserProfile()
    {
        ViewBag.Message = &quot;Modify Your Profile&quot;;
        return View();
    }
&lt;/pre&gt;
&lt;br /&gt;
It is important to point out that MVC 4 has two types of Authroize attributes; one used for controller&#39;s that manage views (System.Web.Mvc.AuthorizeAttribute) and one used for Web API controllers (System.Web.Http.AuthorizeAttribute). Each has very different behavior because of what they are controlling. For this article we discussing how to customize the Authorize attribute for controllers that manage views. We will look at customizing the one for Web API&#39;s in a later article.&lt;br /&gt;
&lt;br /&gt;
So how is resource and operation used to determine what controller actions a user has access to. &amp;nbsp;Users are still assigned to roles, but now we map the roles to resource/operations. &amp;nbsp;For a user to have access the resource/operation must have a role assigned that the user has. &amp;nbsp;Now when we change our security model we do not have to modify any code, instead we configure it in our database. &amp;nbsp;To implement this design we need to customize the &lt;i&gt;SimpleMembership &lt;/i&gt;database. &amp;nbsp;Here is what the new database looks like.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1MtNESy9j-z_Br-PZAOXQAI6rRaok8ze2CQ3B2P0ETGV5x8cZpdbkiMXskYW0Axr-DaqqysDlqnSICupFEWYXnLFYLVaQpMlq-FpayYIAqj6cEfOY-3T3d-CVsra4E8FuIduB98vKqAI/s1600/simpleMembershipDb2.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1MtNESy9j-z_Br-PZAOXQAI6rRaok8ze2CQ3B2P0ETGV5x8cZpdbkiMXskYW0Axr-DaqqysDlqnSICupFEWYXnLFYLVaQpMlq-FpayYIAqj6cEfOY-3T3d-CVsra4E8FuIduB98vKqAI/s1600/simpleMembershipDb2.jpg&quot; width=&quot;218&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
We have added a new table called &lt;i&gt;Resources &lt;/i&gt;which contains all of the resources for the application and &lt;i&gt;Operations&lt;/i&gt; which contains all of the operations for a resource. &amp;nbsp;The relationship between operations and resources is one resource to many operations. &amp;nbsp;Operations are then mapped to roles in the &lt;i&gt;OperationsToRoles &lt;/i&gt;table. &amp;nbsp;This is a many-to-many relationship. To see how these tables were added to the &lt;i&gt;SimpleMembership &lt;/i&gt;database look at the &lt;a href=&quot;https://github.com/kjunghans/SimpleSecurity&quot;&gt;source code in the SimpleSecurity project&lt;/a&gt;. &amp;nbsp;The new entities are defined in SimpleSecurity\Entities. &amp;nbsp;This project uses a Repository and Unit of Work design pattern and you can see the implementation for this in SimpleSecurity\Repositories. &amp;nbsp;The details for the entities configuration and relationships are done using the Fluent API and can be found in SimpleSecurity\Repositories\ModelConfiguration.&lt;br /&gt;
&lt;br /&gt;
So how did we customize the &lt;i&gt;Authorize&lt;/i&gt; attribute to work with resource and operations instead of roles. Lets take a look at the code.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;    [AttributeUsageAttribute(AttributeTargets.Class | AttributeTargets.Method, Inherited = true,
    AllowMultiple = true)]
    public class SimpleAuthorize : AuthorizeAttribute
    {
        public string Resource { get; set; }
        public string Operation { get; set; }

        public override void OnAuthorization(AuthorizationContext actionContext)
        {
            base.Roles = ResourceService.GetRolesAsCsv(Resource, Operation);
            base.OnAuthorization(actionContext);
        }

    }
&lt;/pre&gt;
&lt;br /&gt;
We inherit from the standard &lt;i&gt;AuthorizeAttribute &lt;/i&gt;and override the &lt;i&gt;OnAuthorization &lt;/i&gt;method. &amp;nbsp;The implementation is pretty straight forward. Now we just get a list of the roles assigned to the resource/operation by calling &lt;i&gt;ResourceService.GetRolesAsCsv&lt;/i&gt; (Csv stands for comma separated values) and pass these roles to the base &lt;i&gt;AuthorizeAttribute &lt;/i&gt;class. &amp;nbsp;&lt;i&gt;ResourceService &lt;/i&gt;is an application domain layer on top of the repositories for handling resources and operations.&lt;br /&gt;
&lt;br /&gt;
You can test this out in the example project in &lt;i&gt;SimpleSecurity &lt;/i&gt;called &lt;i&gt;SeedSimple&lt;/i&gt;. &amp;nbsp;&lt;a href=&quot;https://github.com/kjunghans/SimpleSecurity&quot;&gt;Download the source code for this project&lt;/a&gt; and run it to see how it works. &amp;nbsp;I have added two new actions to the &lt;i&gt;HomeController&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;    [SimpleAuthorize(Resource = &quot;Foo&quot;, Operation = &quot;Read&quot;)]
    public ActionResult ReadFoo()
    {
        ViewBag.Message = &quot;Read Foo&quot;;
        return View();
    }

    [SimpleAuthorize(Resource = &quot;Foo&quot;, Operation = &quot;Write&quot;)]
    public ActionResult WriteFoo()
    {
        ViewBag.Message = &quot;Write Foo&quot;;
        return View();
    }
&lt;/pre&gt;
&lt;br /&gt;
I also modified how the database is seeded to add the resources/operations and their role mapping.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;        protected override void Seed(SecurityContext context)
        {

            WebMatrix.WebData.WebSecurity.InitializeDatabaseConnection(&quot;SimpleSecurityConnection&quot;,
               &quot;UserProfile&quot;, &quot;UserId&quot;, &quot;UserName&quot;, autoCreateTables: true);
            var roles = (WebMatrix.WebData.SimpleRoleProvider)Roles.Provider;
            var membership = (WebMatrix.WebData.SimpleMembershipProvider)Membership.Provider;

            if (!roles.RoleExists(&quot;Admin&quot;))
            {
                roles.CreateRole(&quot;Admin&quot;);
            }
            if (!roles.RoleExists(&quot;User&quot;))
            {
                roles.CreateRole(&quot;User&quot;);
            }
            if (!roles.RoleExists(&quot;SuperUser&quot;))
            {
                roles.CreateRole(&quot;SuperUser&quot;);
            }
            if (!WebSecurity.FoundUser(&quot;test&quot;))
            {
                WebSecurity.CreateUserAndAccount(&quot;test&quot;, &quot;password&quot;, &quot;test@gmail.com&quot;);
            }
            if (!roles.GetRolesForUser(&quot;test&quot;).Contains(&quot;Admin&quot;))
            {
                roles.AddUsersToRoles(new[] { &quot;test&quot; }, new[] { &quot;admin&quot; });
            }
            if (!WebSecurity.FoundUser(&quot;joe&quot;))
            {
                WebSecurity.CreateUserAndAccount(&quot;joe&quot;, &quot;password&quot;, &quot;joe@gmail.com&quot;);
            }
            if (!roles.GetRolesForUser(&quot;joe&quot;).Contains(&quot;User&quot;))
            {
                roles.AddUsersToRoles(new[] { &quot;joe&quot; }, new[] { &quot;User&quot; });
            }
            List&amp;lt;operation&amp;gt; operations = new List&amp;lt;operation&amp;gt;();
            operations.Add(new Operation() {Name = &quot;Read&quot;});
            operations.Add(new Operation() {Name = &quot;Write&quot;});
            ResourceService.AddResource(&quot;Foo&quot;, operations);
            ResourceService.MapOperationToRole(&quot;Foo&quot;, &quot;Read&quot;, &quot;User&quot;);
            ResourceService.MapOperationToRole(&quot;Foo&quot;, &quot;Write&quot;, &quot;Admin&quot;);
 
        }
&lt;/pre&gt;
&lt;br /&gt;
As you can see from this code the resource/operation&lt;i&gt; Foo/Read&lt;/i&gt; is assigned to the role of &lt;i&gt;User &lt;/i&gt;and &lt;i&gt;Foo/Write&lt;/i&gt; is assigned to the role of &lt;i&gt;Admin&lt;/i&gt;. &amp;nbsp; The user &lt;i&gt;joe &lt;/i&gt;is assigned the role &lt;i&gt;User &lt;/i&gt;and the user &lt;i&gt;test &lt;/i&gt;is assigned to the role &lt;i&gt;Admin&lt;/i&gt;. &lt;br /&gt;
&lt;br /&gt;
Run the application and select the tab Read Foo. &amp;nbsp;If you are not logged in you will be taken to the logon page. Log in as &lt;i&gt;joe &lt;/i&gt;with the password of &lt;i&gt;password&lt;/i&gt;. You will be redirected to the Read Foo page because joe has authorization for this page. Now select the Write Foo tab and again you will be redirected to the logon page because joe does not have authorization for this page. Log in as the user &lt;i&gt;test &lt;/i&gt;and you will be redirected to the Write Foo page because user test does have authorization.&lt;br /&gt;
&lt;br /&gt;
So now we can use SimpleMembership without worrying about our security model changing. We can change our security model by just changing our database configuration instead of making code changes, recompiling them and redeploying. &amp;nbsp;Another benefit is we can defer designing our security model until we are ready to deploy. We no longer have to design our security model while we are implementing the application. What do you think about this design? &amp;nbsp;Please let me know your thoughts in the comments.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
 SyntaxHighlighter.highlight();
&lt;/script&gt;</content><link rel='replies' type='application/atom+xml' href='http://kevin-junghans.blogspot.com/feeds/8410338906705712239/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kevin-junghans.blogspot.com/2013/08/decoupling-you-security-model-from.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2016746845209941562/posts/default/8410338906705712239'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2016746845209941562/posts/default/8410338906705712239'/><link rel='alternate' type='text/html' href='http://kevin-junghans.blogspot.com/2013/08/decoupling-you-security-model-from.html' title='Decoupling You Security Model From The Application Model With SimpleMembership'/><author><name>Kevin Junghans</name><uri>http://www.blogger.com/profile/01125287678342544067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1MtNESy9j-z_Br-PZAOXQAI6rRaok8ze2CQ3B2P0ETGV5x8cZpdbkiMXskYW0Axr-DaqqysDlqnSICupFEWYXnLFYLVaQpMlq-FpayYIAqj6cEfOY-3T3d-CVsra4E8FuIduB98vKqAI/s72-c/simpleMembershipDb2.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2016746845209941562.post-8399622469016544648</id><published>2013-04-25T10:59:00.000-04:00</published><updated>2013-07-25T09:20:33.597-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ASP.Net"/><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="MVC 4"/><category scheme="http://www.blogger.com/atom/ns#" term="security"/><category scheme="http://www.blogger.com/atom/ns#" term="SimpleMembership"/><title type='text'>Using Code-First Migration With SimpleMembership</title><content type='html'>In previous posts I have written about &lt;a href=&quot;http://kevin-junghans.blogspot.com/2013/01/seeding-customizing-aspnet-mvc.html&quot; target=&quot;_blank&quot;&gt;customizing and seeding SimpleMembership&lt;/a&gt;, the newest membership provider used in ASP.NET MVC 4 Internet applications. &amp;nbsp;In the example in this previous post we setup a database&amp;nbsp;initializer&amp;nbsp;that can be set to either to a type of &lt;i&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/gg679506(v=vs.103).aspx&quot; target=&quot;_blank&quot;&gt;DropCreateDatabaseAlways &lt;/a&gt;&lt;/i&gt;or&amp;nbsp;&lt;i&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/gg679604(v=vs.103).aspx&quot; target=&quot;_blank&quot;&gt;DropCreateDatabaseIfModelChanges&lt;/a&gt;.&lt;/i&gt;&amp;nbsp;As the name implies &lt;i&gt;DropCreateDatabaseAlways &lt;/i&gt;will drop the database and recreate it every time the initializer is called, which is at application start, and will run the method to seed the database after creation. &amp;nbsp;&lt;i&gt;DropCreateDatabaseIfModelChanges &lt;/i&gt;varies in that it will only recreate the database if the database model changes in your code. &amp;nbsp;Both of these approaches work great during development and unit testing but you would not want to deploy the solution this way for production. &amp;nbsp;This is where code-first migration comes in.&lt;br /&gt;
&lt;br /&gt;
Code-first migration allows you to update the database without having to recreate it and therefore loosing the data that is already in the database. &amp;nbsp;An obvious must have for production systems. To show how we can implement this in SimpleMembership I will start with the decoupled version of SimpleMembership called &lt;a href=&quot;https://simplesecurity.codeplex.com/&quot; target=&quot;_blank&quot;&gt;SimpleSecurity&lt;/a&gt;. &amp;nbsp;You can &lt;a href=&quot;http://kevin-junghans.blogspot.com/2013/03/decoupling-simplemembership-from-your.html&quot; target=&quot;_blank&quot;&gt;read about SimpleSecurity and the concept behind it here&lt;/a&gt;. &amp;nbsp;It turns out that adding migration is fairly straight forward. To follow along you can &lt;a href=&quot;https://simplesecurity.codeplex.com/SourceControl/BrowseLatest&quot; target=&quot;_blank&quot;&gt;download the project for SimpleSecurity here&lt;/a&gt;. &amp;nbsp;Note that if you get the latest version it will already have migration enable, but I will cover the steps here so that you can do this from scratch if needed.&lt;br /&gt;
&lt;br /&gt;
To enable migrations go to the Package Manager Console and make sure your default project in the console is set to the project that contains your data layer (i.e. DbContext). For SimpleSecurity the project with the data layer is also called SimpleSecurity. Then enter the command &quot;enable-migrations&quot;. &amp;nbsp;This will create a new folder in your data layer project called Migrations and it will contain a new file named Configurations.cs. If Entity Framework can find your database and detect any changes it will also create a CSharp file that contains code for the initial migration. &amp;nbsp;The Configuration file contains this code.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;    internal sealed class Configuration : DbMigrationsConfiguration&amp;lt;SimpleSecurity.Repositories.SecurityContext&amp;gt;
    {
        public Configuration()
        {
            AutomaticMigrationsEnabled = true;
        }

        protected override void Seed(SimpleSecurity.Repositories.SecurityContext context)
        {
            //  This method will be called after migrating to the latest version.

            //  You can use the DbSet&amp;lt;T&amp;gt;.AddOrUpdate() helper extension method 
            //  to avoid creating duplicate seed data. E.g.
            //
            //    context.People.AddOrUpdate(
            //      p =&amp;gt; p.FullName,
            //      new Person { FullName = &quot;Andrew Peters&quot; },
            //      new Person { FullName = &quot;Brice Lambson&quot; },
            //      new Person { FullName = &quot;Rowan Miller&quot; }
            //    );
            //
        }
    }
&lt;/pre&gt;
&lt;br /&gt;
This is the new database initializer that will be used for database migration. &amp;nbsp;When EF creates this the setting for &lt;i&gt;AutomaticMigrationsEnabled &lt;/i&gt;is set to false. I changed this to true so we can start with automatic migrations. &amp;nbsp;The other type of migration is called code-based migrations. &amp;nbsp;Code-based migration is much more powerful and the likely choice for production system because of the control it provides. &amp;nbsp;But it is a much larger topic that we will have to cover in later posts. &amp;nbsp;So for this article we will just cover automatic migrations.&lt;br /&gt;
&lt;br /&gt;
If you recall from the article on&amp;nbsp;&lt;a href=&quot;http://kevin-junghans.blogspot.com/2013/01/seeding-customizing-aspnet-mvc.html&quot; target=&quot;_blank&quot;&gt;Seeding &amp;amp; Customizing ASP.NET MVC SimpleMembership&lt;/a&gt;&amp;nbsp;we set which initializer to use in code using the &lt;i&gt;SetInitializer &lt;/i&gt;method.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:csharp&quot;&gt; Database.SetInitializer&amp;lt;userscontext&amp;gt;(new InitSecurityDb());
 UsersContext context = new UsersContext();
 context.Database.Initialize(true);
 if (!WebSecurity.Initialized)
    WebSecurity.InitializeDatabaseConnection(&quot;DefaultConnection&quot;,
         &quot;UserProfile&quot;, &quot;UserId&quot;, &quot;UserName&quot;, autoCreateTables: true);

&lt;/pre&gt;
&lt;br /&gt;
We cannot do that with the &lt;i&gt;Configuration &lt;/i&gt;class because it is defined as&lt;i&gt; internal sealed.&lt;/i&gt; If we wanted to set it programmatically there is no problem with changing to the&amp;nbsp;definition&amp;nbsp;of &lt;i&gt;Configuration &lt;/i&gt;to &lt;i&gt;public&lt;/i&gt;. &amp;nbsp;But the better way to do this is to set it in the web.config like this.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;  &amp;lt;entityFramework&amp;gt;
    &amp;lt;defaultConnectionFactory type=&quot;System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework&quot; /&amp;gt;
    &amp;lt;contexts&amp;gt;
      &amp;lt;!--Use this initializer if you want to use datbase migration--&amp;gt;
      &amp;lt;context type=&quot;SimpleSecurity.Repositories.SecurityContext, SimpleSecurity&quot; disableDatabaseInitialization=&quot;false&quot;&amp;gt;
        &amp;lt;databaseInitializer
          type=&quot;System.Data.Entity.MigrateDatabaseToLatestVersion`2[[SimpleSecurity.Repositories.SecurityContext, SimpleSecurity],
               [SimpleSecurity.Migrations.Configuration,  SimpleSecurity]], EntityFramework&quot; /&amp;gt;
      &amp;lt;/context&amp;gt;
      &amp;lt;!--Use this initializer if you are testing and want to create a new database for each test.--&amp;gt;
      &amp;lt;!--&amp;lt;context disabledatabaseinitialization=&quot;false&quot; type=&quot;SimpleSecurity.Repositories.SecurityContext, SimpleSecurity&quot;&amp;gt;
        &amp;lt;databaseInitializer
          type=&quot;SimpleSecurity.DropCreateSecurityDb, SimpleSecurity&quot; /&amp;gt;
      &amp;lt;/context&amp;gt;--&amp;gt;
    &amp;lt;/contexts&amp;gt;
  &amp;lt;/entityFramework&amp;gt;

&lt;/pre&gt;
&lt;br /&gt;
You will notice that I have two initializers set in this configuration with one being commented out. &amp;nbsp;The one that is not commented is the one for migrations, the one that is commented out is for an initializer that performs a drop-create. &amp;nbsp;This way I can easily switch between the initializers since I may want to use the drop-create initializer during testing. Now we can easily set our initializers through a configuration change. Just be sure to remember to remove &lt;i&gt;Database.SetInitializer&lt;/i&gt; from your code.&lt;br /&gt;
&lt;br /&gt;
Now when you have it configured for automatic migrations any changes to your model will automatically update the database with these changes without loosing your data, with one exception. If you remove a property from the model and there is data in the corresponding column in a table the migration will throw an exception. If you want to allow the removal of a column with data you need to set&amp;nbsp;&lt;i&gt;AutomaticMigrationDataLossAllowed &lt;/i&gt;to &lt;i&gt;true &lt;/i&gt;in the &lt;i&gt;Configuration &lt;/i&gt;class constructor. &lt;br /&gt;
&lt;br /&gt;
Automatic &amp;nbsp;migration is a powerful feature of Entity Framework. &amp;nbsp;Look for future posts where we will discuss code-based migrations.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
 SyntaxHighlighter.highlight();
&lt;/script&gt;</content><link rel='replies' type='application/atom+xml' href='http://kevin-junghans.blogspot.com/feeds/8399622469016544648/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kevin-junghans.blogspot.com/2013/04/using-code-first-migration-with.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2016746845209941562/posts/default/8399622469016544648'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2016746845209941562/posts/default/8399622469016544648'/><link rel='alternate' type='text/html' href='http://kevin-junghans.blogspot.com/2013/04/using-code-first-migration-with.html' title='Using Code-First Migration With SimpleMembership'/><author><name>Kevin Junghans</name><uri>http://www.blogger.com/profile/01125287678342544067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2016746845209941562.post-1341664751215941494</id><published>2013-04-22T21:17:00.000-04:00</published><updated>2013-04-22T21:35:59.859-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ASP.Net"/><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="MVC 4"/><category scheme="http://www.blogger.com/atom/ns#" term="SimpleMembership"/><title type='text'>Using SimpleMembership With Mobile Applications In ASP.NET MVC 4</title><content type='html'>Someone recently &lt;a href=&quot;http://stackoverflow.com/questions/16144278/simplemembershipprovider-in-mobile-app-asp-net-mvc-4&quot; target=&quot;_blank&quot;&gt;asked on StackOverflow if you can use the SimpleMembership provider in a mobile application&lt;/a&gt; generated by the mobile template for ASP.NET MVC 4. &amp;nbsp;The shell of the mobile application generated by this template generates basic security, such as logging in, logging out, registration and password reset, but it uses the older ASP.NET membership and role providers. &amp;nbsp;So I thought this would be a good exercise to see if I could use the &lt;a href=&quot;https://simplesecurity.codeplex.com/&quot; target=&quot;_blank&quot;&gt;open source project &lt;i&gt;SimpleSecurity&lt;/i&gt;&lt;/a&gt;&lt;i&gt; &lt;/i&gt;to switch the mobile application to use the SimpleMembershipProvider. &amp;nbsp;&lt;a href=&quot;http://kevin-junghans.blogspot.com/2013/03/decoupling-simplemembership-from-your.html&quot; target=&quot;_blank&quot;&gt;&lt;i&gt;SimpleSecurity &lt;/i&gt;helps decouple &lt;i&gt;SimpleMembership &lt;/i&gt;from an MVC application&lt;/a&gt;. &amp;nbsp;It turns out that it was quite easy to add &lt;i&gt;SimpleMembership &lt;/i&gt;to an ASP.NET MVC mobile application when using &lt;i&gt;SimpleSecurity&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
First add the &lt;i&gt;SimpleSecurity &lt;/i&gt;assembly as a reference in your mobile project. You will also need to add &lt;i&gt;WebMatrix.Data&lt;/i&gt; and &lt;i&gt;WebMatrix.WebData&lt;/i&gt; as references. In the properties for these two assemblies set the property Copy Local to true.&lt;br /&gt;
&lt;br /&gt;
Next modify your web.config to use the SimpleMembership providers. &amp;nbsp;Replace the settings for the providers in the template generated web.config to the following.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;    &amp;lt;roleManager enabled=&quot;true&quot; defaultProvider=&quot;SimpleRoleProvider&quot;&amp;gt;
      &amp;lt;providers&amp;gt;
        &amp;lt;clear/&amp;gt;
        &amp;lt;add name=&quot;SimpleRoleProvider&quot; type=&quot;WebMatrix.WebData.SimpleRoleProvider, WebMatrix.WebData&quot;/&amp;gt;
      &amp;lt;/providers&amp;gt;
    &amp;lt;/roleManager&amp;gt;
    &amp;lt;membership defaultProvider=&quot;SimpleMembershipProvider&quot;&amp;gt;
      &amp;lt;providers&amp;gt;
        &amp;lt;clear/&amp;gt;
        &amp;lt;add name=&quot;SimpleMembershipProvider&quot; type=&quot;WebMatrix.WebData.SimpleMembershipProvider, WebMatrix.WebData&quot; /&amp;gt;
      &amp;lt;/providers&amp;gt;
    &amp;lt;/membership&amp;gt;

&lt;/pre&gt;
Add the following line to the &lt;i&gt;Application_Start&lt;/i&gt; method in the Global.asax to register &lt;i&gt;SimpleSecurity&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;    WebSecurity.Register();

&lt;/pre&gt;
&lt;br /&gt;
Finally we need to modify the actions in the &lt;i&gt;AccountController &lt;/i&gt;that were generated by the mobile template.  Here are the modifications 
to the POST &lt;i&gt;Login&lt;/i&gt; action.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;        [AllowAnonymous]
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Login(LoginModel model, string returnUrl)
        {
            if (ModelState.IsValid)
            {
                if (WebSecurity.Login(model.UserName, model.Password, model.RememberMe))
                {
                    if (Url.IsLocalUrl(returnUrl))
                    {
                        return Redirect(returnUrl);
                    }
                    else
                    {
                        return RedirectToAction(&quot;Index&quot;, &quot;Home&quot;);
                    }
                }
                else
                {
                    ModelState.AddModelError(&quot;&quot;, &quot;The user name or password provided is incorrect.&quot;);
                }
            }

            // If we got this far, something failed, redisplay form
            return View(model);
        }

&lt;/pre&gt;
&lt;br /&gt;
And here are the changes to the &lt;i&gt;LogOff &lt;/i&gt;action.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;       public ActionResult LogOff()
       {
           WebSecurity.Logout();

           return RedirectToAction(&quot;Index&quot;, &quot;Home&quot;);
       }

&lt;/pre&gt;
&lt;br /&gt;
You will also need to change the &lt;i&gt;Register &lt;/i&gt;action.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;        [AllowAnonymous]
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Register(RegisterModel model)
        {
            if (ModelState.IsValid)
            {
                // Attempt to register the user
                bool createdUser = false;
                string errMessage = string.Empty;
                try
                {
                    WebSecurity.CreateUserAndAccount(model.UserName, model.Password, model.Email);
                    createdUser = true;

                }
                catch (Exception ex)
                {
                    errMessage = ex.Message;
                    createdUser = false; 
                }

                if (createdUser)
                {
                    if (WebSecurity.Login(model.UserName, model.Password))
                        return RedirectToAction(&quot;Index&quot;, &quot;Home&quot;);
                    else
                        ModelState.AddModelError(&quot;&quot;, &quot;Error logging user in with that username/password.&quot;);

                }
                else
                {
                    ModelState.AddModelError(&quot;&quot;, errMessage);
                }
            }

            // If we got this far, something failed, redisplay form
            return View(model);
        }

&lt;/pre&gt;
&lt;br /&gt;
And lets not forget the &lt;i&gt;ChangePassword&lt;/i&gt; action.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult ChangePassword(ChangePasswordModel model)
        {
            if (ModelState.IsValid)
            {

                // ChangePassword will throw an exception rather
                // than return false in certain failure scenarios.
                bool changePasswordSucceeded;
                try
                {
                    UserProfile currUser = WebSecurity.GetCurrentUser();
                    changePasswordSucceeded = WebSecurity.ChangePassword(currUser.UserName, model.OldPassword, model.NewPassword);
                }
                catch (Exception)
                {
                    changePasswordSucceeded = false;
                }

                if (changePasswordSucceeded)
                {
                    return RedirectToAction(&quot;ChangePasswordSuccess&quot;);
                }
                else
                {
                    ModelState.AddModelError(&quot;&quot;, &quot;The current password is incorrect or the new password is invalid.&quot;);
                }
            }

&lt;/pre&gt;
&lt;br /&gt;
That is it. Your mobile application will now use the &lt;i&gt;SimpleMembership&lt;/i&gt; provider instead of the old-style ASP.NET providers.  If you would like the source code for this example you can &lt;a href=&quot;https://simplesecurity.codeplex.com/SourceControl/BrowseLatest&quot; target=&quot;_blank&quot;&gt;get it here&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;iframe bordercolor=&quot;#000000&quot; frameborder=&quot;0&quot; height=&quot;250&quot; hspace=&quot;0&quot; marginheight=&quot;0&quot; marginwidth=&quot;0&quot; scrolling=&quot;no&quot; src=&quot;http://ad.doubleclick.net/adi/N7433.148119.BLOGGEREN/B6631428.130974;sz=300x250;ord=[timestamp]?;lid=41000613802464048;pid=22383804;usg=AFHzDLvJFhohP0Rz2vzMwcZQt0-N2XlwJw;adurl=http%253A%252F%252Fwww.officemax.com%252Ftechnology%252Fsoftware%252Fgraphics-design-software%252Fproduct-prod3210108%253Fcm_mmc%253DPerformics-_-Technology-_-Software-_-Graphics%252520and%252520Design%252520Software%2526ci_src%253D14110944%2526ci_sku%253D22383804;pubid=633976;price=%2479.98;title=Microsoft+Expression+Studio+Web+Professional+4.0+Upgrade+NHF-00001;merc=OfficeMax;imgsrc=http%3A%2F%2Fwww.officemax.com%2Fcatalog%2Fimages%2F397x353%2F22383804i_01.jpg;width=151;height=135&quot; vspace=&quot;0&quot; width=&quot;300&quot;&gt;&lt;/iframe&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
 SyntaxHighlighter.highlight();
&lt;/script&gt;</content><link rel='replies' type='application/atom+xml' href='http://kevin-junghans.blogspot.com/feeds/1341664751215941494/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kevin-junghans.blogspot.com/2013/04/using-simplemembership-with-mobile.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2016746845209941562/posts/default/1341664751215941494'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2016746845209941562/posts/default/1341664751215941494'/><link rel='alternate' type='text/html' href='http://kevin-junghans.blogspot.com/2013/04/using-simplemembership-with-mobile.html' title='Using SimpleMembership With Mobile Applications In ASP.NET MVC 4'/><author><name>Kevin Junghans</name><uri>http://www.blogger.com/profile/01125287678342544067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2016746845209941562.post-5925414153763876620</id><published>2013-04-11T11:21:00.001-04:00</published><updated>2013-04-11T11:21:35.097-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ASP.Net"/><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="MVC 4"/><category scheme="http://www.blogger.com/atom/ns#" term="SimpleMembership"/><title type='text'>Password Reset with SimpleMembership</title><content type='html'>SimpleMembership is the new security provider that is bundled with ASP.NET MVC 4 when you use the Internet Template to create a new application. &amp;nbsp;In this article I will demonstrate how to add password reset to your MVC application using SimpleMembership. For this demonstration I will use &lt;a href=&quot;https://simplesecurity.codeplex.com/&quot; target=&quot;_blank&quot;&gt;SimpleSecurity&lt;/a&gt;, an open source project that &lt;a href=&quot;http://kevin-junghans.blogspot.com/2013/03/decoupling-simplemembership-from-your.html&quot; target=&quot;_blank&quot;&gt;decouples SimpleSecurity from your MVC application&lt;/a&gt;. The concepts in this article still apply if you do not use SimpleSecurity and you just want to use SimpleMembership directly.&lt;br /&gt;
&lt;br /&gt;
The basic steps for changing a password when using SimpleMembership is to first generate a unique token that is emailed to the user as a link. &amp;nbsp;Then the user clicks on the link passing the token in the query string. The user is presented with a web page to enter the new password and when they submit it the token is verified and if it passes the new password is updated in the users membership information. This method of password reset is very flexible since it can be used to just change the password, as well as allow a user to reset their password if they forgot it.&lt;br /&gt;
&lt;br /&gt;
This method of password reset only works if we confirmed the email address during the registration process. &amp;nbsp;&lt;a href=&quot;http://kevin-junghans.blogspot.com/2013/02/adding-email-confirmation-to.html&quot; target=&quot;_blank&quot;&gt;Read this article&lt;/a&gt; to see how to add email confirmation to the registration process. &amp;nbsp;The advantage of using SimpleSecurity is that it is already configured to support email confirmation. &amp;nbsp;Just as in the email confirmation for registration we will use &lt;a href=&quot;http://aboutcode.net/postal/&quot; target=&quot;_blank&quot;&gt;Postal &lt;/a&gt;to send the email for password reset.&lt;br /&gt;
&lt;br /&gt;
To start the password reset process I added an action link to the log-in page for the user to click on.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-c2X39Os093VkYcb2S0NwfCVVVhGa1zsGzieoYIlvdxdvAol1Jb6EBl9F3goec4poTH-asQoaHXcfpVad8qxESc20hgrw2MlCFWkXMesQyyRcWypeZMf_Rh6FJasP-QQtyMAnUV1YJe8/s1600/forgotPassword.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-c2X39Os093VkYcb2S0NwfCVVVhGa1zsGzieoYIlvdxdvAol1Jb6EBl9F3goec4poTH-asQoaHXcfpVad8qxESc20hgrw2MlCFWkXMesQyyRcWypeZMf_Rh6FJasP-QQtyMAnUV1YJe8/s1600/forgotPassword.jpg&quot; height=&quot;269&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
When the user clicks on the link they are taken to another page which asks them to enter their user name and press the &lt;i&gt;Reset Password&lt;/i&gt; button.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHGlzlNyzSjoja1mmjvyHZJ7-TSEuO0KZDAG3i4F8A65dnyXn_yhTNd-5Z1p7aaFSP166fLqShKrxME1p-KngxLgrpRe-hbEZmZxen-TJX_B57UQNPBDFCq-GzceWizNfJL3KWbCJsbTM/s1600/resetPassword..jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHGlzlNyzSjoja1mmjvyHZJ7-TSEuO0KZDAG3i4F8A65dnyXn_yhTNd-5Z1p7aaFSP166fLqShKrxME1p-KngxLgrpRe-hbEZmZxen-TJX_B57UQNPBDFCq-GzceWizNfJL3KWbCJsbTM/s1600/resetPassword..jpg&quot; height=&quot;320&quot; width=&quot;231&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Pressing this button sends control to the action &lt;i&gt;PasswordReset&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;        [AllowAnonymous]
        [HttpPost]
        public ActionResult ResetPassword(ResetPasswordModel model)
        {
            string emailAddress = WebSecurity.GetEmail(model.UserName);
            if (!string.IsNullOrEmpty(emailAddress))
            {
                string confirmationToken =
                    WebSecurity.GeneratePasswordResetToken(model.UserName);
                dynamic email = new Email(&quot;ChngPasswordEmail&quot;);
                email.To = emailAddress;
                email.UserName = model.UserName;
                email.ConfirmationToken = confirmationToken;
                email.Send();

                return RedirectToAction(&quot;ResetPwStepTwo&quot;);
            }

            return RedirectToAction(&quot;InvalidUserName&quot;);
        }

&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
First this method gets the user email address based on the user name. &amp;nbsp;Note that in this example I am using &lt;i&gt;SimpleSecurity.WebSecurity&lt;/i&gt; instead of &lt;i&gt;WebMatrix.WebData.WebSecurity&lt;/i&gt;, which has methods for retrieving the email address. If you are using straight &lt;i&gt;SimpleMembership &lt;/i&gt;you will need to develop your own methods to do this, which is&amp;nbsp;&lt;a href=&quot;http://kevin-junghans.blogspot.com/2013/01/seeding-customizing-aspnet-mvc.html&quot; target=&quot;_blank&quot;&gt;described in this article&lt;/a&gt;. &amp;nbsp;If we do not get an email then the user name is invalid and we present the user with a view that lets them know. &amp;nbsp;If we have a good email we generated the password reset token by calling &lt;i&gt;WebSecurity.GeneratePasswordResetToken&lt;/i&gt; with the user name, then create and send the email using Postal. If this is successful we take the user to view that lets them know an email has been sent to them with further instructions for&amp;nbsp;resetting&amp;nbsp;the password.&lt;br /&gt;
&lt;br /&gt;
When the user clicks on the link in the email they are directed to the action &lt;i&gt;ResetPasswordConfirmation&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;        [AllowAnonymous]
        public ActionResult ResetPasswordConfirmation(string Id)
        {
            ResetPasswordConfirmModel model = new ResetPasswordConfirmModel() { Token = Id };
            return View(model);
        }

&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
This action gets the token from the query string and puts it in the &lt;i&gt;ResetPasswordConfirmationModel &lt;/i&gt;that is passed to the view which allows the user to enter the new password. The new password is entered twice to make sure they entered it correctly. When they submit this information they are taken to the &lt;i&gt;POST &lt;/i&gt;version of this action.
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;       [AllowAnonymous]
        [HttpPost]
        public ActionResult ResetPasswordConfirmation(ResetPasswordConfirmModel model)
        {
            if (WebSecurity.ResetPassword(model.Token, model.NewPassword))
            {
                return RedirectToAction(&quot;PasswordResetSuccess&quot;);
            }
            return RedirectToAction(&quot;PasswordResetFailure&quot;);
        }

&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
This action gets the token and new password from the model passed back from the view and calls &lt;i&gt;WebSecurity.ResetPassword&lt;/i&gt; to do the actual password reset. &amp;nbsp;If it is successful the user is presented with a view letting them know that the password was reset and that they should log on with their new password. If it fails they are presented with a&amp;nbsp;view&amp;nbsp;that tells them as such.&lt;br /&gt;
&lt;br /&gt;
That is the&amp;nbsp;fundamentals of adding a password reset to an ASP.NET MVC application with SimpleMembership. If you would like the complete source code for this example you can &lt;a href=&quot;https://simplesecurity.codeplex.com/SourceControl/BrowseLatest&quot; target=&quot;_blank&quot;&gt;get it here&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
 SyntaxHighlighter.highlight();
&lt;/script&gt;</content><link rel='replies' type='application/atom+xml' href='http://kevin-junghans.blogspot.com/feeds/5925414153763876620/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kevin-junghans.blogspot.com/2013/04/password-reset-with-simplemembership.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2016746845209941562/posts/default/5925414153763876620'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2016746845209941562/posts/default/5925414153763876620'/><link rel='alternate' type='text/html' href='http://kevin-junghans.blogspot.com/2013/04/password-reset-with-simplemembership.html' title='Password Reset with SimpleMembership'/><author><name>Kevin Junghans</name><uri>http://www.blogger.com/profile/01125287678342544067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-c2X39Os093VkYcb2S0NwfCVVVhGa1zsGzieoYIlvdxdvAol1Jb6EBl9F3goec4poTH-asQoaHXcfpVad8qxESc20hgrw2MlCFWkXMesQyyRcWypeZMf_Rh6FJasP-QQtyMAnUV1YJe8/s72-c/forgotPassword.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2016746845209941562.post-5237497944894632587</id><published>2013-04-02T11:36:00.005-04:00</published><updated>2013-06-28T09:09:34.647-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ASP.Net"/><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="MVC 4"/><category scheme="http://www.blogger.com/atom/ns#" term="open source"/><category scheme="http://www.blogger.com/atom/ns#" term="security"/><category scheme="http://www.blogger.com/atom/ns#" term="SimpleMembership"/><title type='text'>Retrieving Confirmation Token in SimpleMembership</title><content type='html'>A reader commented on my blog &quot;&lt;i&gt;&lt;a href=&quot;http://kevin-junghans.blogspot.com/2013/02/adding-email-confirmation-to.html&quot; target=&quot;_blank&quot;&gt;Adding Email Confirmation to SimpleMembership&lt;/a&gt;&lt;/i&gt;&quot; that they would like the ability to resend the email confirmation to users that did not&amp;nbsp;receive&amp;nbsp;it for whatever reason. &amp;nbsp;This seemed like a reasonable request and it is actually asked a lot on various forums. &amp;nbsp;The problem is that &lt;i&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/webmatrix.webdata.websecurity(v=vs.111).aspx&quot; target=&quot;_blank&quot;&gt;WebMatrix.WebData.WebSecurity&lt;/a&gt;&lt;/i&gt; does not provide a method to retrieve the confirmation token so that you can resend the email. &amp;nbsp;The token is only provided when you call &lt;i&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/webmatrix.webdata.websecurity.createuserandaccount(v=vs.111).aspx&quot; target=&quot;_blank&quot;&gt;CreateUserAndAccount&lt;/a&gt;&lt;/i&gt; and set &lt;i&gt;requireConfirmationToken &lt;/i&gt;to true. &amp;nbsp;It turns out the only way to get the confirmation token in &lt;i&gt;SimpleMembership &lt;/i&gt;is to directly query the &lt;i&gt;webpages_Membership &lt;/i&gt;table. &amp;nbsp;I have encapsulated this functionality in the open source project called &lt;i&gt;&lt;a href=&quot;https://simplesecurity.codeplex.com/&quot; target=&quot;_blank&quot;&gt;SimpleSecurity&lt;/a&gt;&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
SimpleSecurity encapsulates WebSecurity and adds missing features like getting the confirmation token. It also decouples the security model from the ASP.NET MVC framework. &amp;nbsp;Now you can just call &lt;a href=&quot;http://simplesecurity.codeplex.com/SourceControl/latest#SimpleSecurity/WebSecurity.cs&quot;&gt;SimpleSecurity.WebSecurity.GetConfirmationToken&lt;/a&gt; with the user name as a parameter and it will return the confirmation token. &amp;nbsp;I have added an example of how to resend the registration email in the reference application in this project which is called &lt;i&gt;SeedSimple&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
In the example I use the login page to allow the user to resend the email. &amp;nbsp;When the user logs in, if they fail authentication then I check if the user is in the system and if they have not completed the confirmation process. If they are not confirmed I provide them with a message informing them to look for the email to complete the registration process or to resend the email. &amp;nbsp;Here is what that page looks like.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYVTjHeWqwjFAYxj1vYgkACFLxCmDrqjkE6_FSVEgeyqyKue-rP8YH0jo5JIORf72WFU-Z2FNsixrVlTetx8RKwIhTjb7hr9PtzymgERBWvl4o_ZZEIDAn2gB7ZixIt1_8g9MpCAXM83M/s1600/resendEmailConf.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYVTjHeWqwjFAYxj1vYgkACFLxCmDrqjkE6_FSVEgeyqyKue-rP8YH0jo5JIORf72WFU-Z2FNsixrVlTetx8RKwIhTjb7hr9PtzymgERBWvl4o_ZZEIDAn2gB7ZixIt1_8g9MpCAXM83M/s1600/resendEmailConf.jpg&quot; height=&quot;269&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Here are the modifications to the Login action to make this work.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:csharp&quot;&gt;       public ActionResult Login(LoginModel model, string returnUrl)
        {
            string errorMsg = &quot;The user name or password provided is incorrect.&quot;;

            if (model.IsConfirmed)
            {
                if (ModelState.IsValid &amp;amp;&amp;amp; WebSecurity.Login(model.UserName, model.Password, persistCookie: model.RememberMe))
                {
                    return RedirectToLocal(returnUrl);
                }
                else if (WebSecurity.FoundUser(model.UserName) &amp;amp;&amp;amp; !WebSecurity.IsConfirmed(model.UserName))
                {
                    model.IsConfirmed = false;
                    errorMsg = &quot;You have not completed the registration process. To complete this process look for the email that provides instructions or press the button to resend the email.&quot;;
                }

            }
            else //Need to resend confirmation email
            {
                ResendConfirmationEmail(model.UserName);
                errorMsg = &quot;The registration email has been resent. Find the email and follow the instructions to complete the registration process.&quot;;
                model.IsConfirmed = true;
            }

            // If we got this far, something failed, redisplay form
            ModelState.AddModelError(&quot;&quot;, errorMsg );
            return View(model);
        }

&lt;/pre&gt;
I modified the &lt;i&gt;LoginModel &lt;/i&gt;to include a flag named &lt;i&gt;IsConfirmed &lt;/i&gt;which lets me manage the state of the view that is displayed and whether I should try to authenticate the user or resend the email confirmation. The method to resend the email confirmation look like this.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:csharp&quot;&gt;        private void ResendConfirmationEmail(string username)
        {
            string email = WebSecurity.GetEmail(username);
            string token = WebSecurity.GetConfirmationToken(username);
            SendEmailConfirmation(email, username, token);
        }

&lt;/pre&gt;
There were also some changes to the &lt;i&gt;Login &lt;/i&gt;view to make this work. &amp;nbsp;You can get the &lt;a href=&quot;https://simplesecurity.codeplex.com/SourceControl/BrowseLatest&quot; target=&quot;_blank&quot;&gt;source code for this project here&lt;/a&gt;. &amp;nbsp;And if you have any suggestion on how to improve &lt;i&gt;SimpleSecurity &lt;/i&gt;you can &lt;a href=&quot;https://simplesecurity.codeplex.com/workitem/list/basic&quot; target=&quot;_blank&quot;&gt;post them here&lt;/a&gt;&amp;nbsp;or just comment on this blog.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
 SyntaxHighlighter.highlight();
&lt;/script&gt;</content><link rel='replies' type='application/atom+xml' href='http://kevin-junghans.blogspot.com/feeds/5237497944894632587/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kevin-junghans.blogspot.com/2013/04/retrieving-confirmation-token-in.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2016746845209941562/posts/default/5237497944894632587'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2016746845209941562/posts/default/5237497944894632587'/><link rel='alternate' type='text/html' href='http://kevin-junghans.blogspot.com/2013/04/retrieving-confirmation-token-in.html' title='Retrieving Confirmation Token in SimpleMembership'/><author><name>Kevin Junghans</name><uri>http://www.blogger.com/profile/01125287678342544067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYVTjHeWqwjFAYxj1vYgkACFLxCmDrqjkE6_FSVEgeyqyKue-rP8YH0jo5JIORf72WFU-Z2FNsixrVlTetx8RKwIhTjb7hr9PtzymgERBWvl4o_ZZEIDAn2gB7ZixIt1_8g9MpCAXM83M/s72-c/resendEmailConf.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2016746845209941562.post-3519570020321040288</id><published>2013-03-26T12:27:00.001-04:00</published><updated>2013-03-26T12:27:10.453-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ASP.Net"/><category scheme="http://www.blogger.com/atom/ns#" term="MVC 4"/><category scheme="http://www.blogger.com/atom/ns#" term="notification"/><category scheme="http://www.blogger.com/atom/ns#" term="outbound"/><category scheme="http://www.blogger.com/atom/ns#" term="Prophecy"/><category scheme="http://www.blogger.com/atom/ns#" term="Tropo"/><category scheme="http://www.blogger.com/atom/ns#" term="Twilio"/><category scheme="http://www.blogger.com/atom/ns#" term="VoiceModel"/><category scheme="http://www.blogger.com/atom/ns#" term="Voxeo"/><title type='text'>Create Proactive Notification Applications with VoiceModel</title><content type='html'>The &lt;a href=&quot;http://voicemodel.codeplex.com/releases/view/104059&quot; target=&quot;_blank&quot;&gt;latest release of VoiceModel&lt;/a&gt; now provides support for developing Proactive Notification Applications using a telephone. &amp;nbsp;Proactive notifications are used to notify customers of important events or information that they are interested in. &amp;nbsp;The media channel currently supported by VoiceModel is voice over the telephone. &amp;nbsp;Some notification systems also support channels such as SMS and email. An example application would be a pharmacy notifying you that your prescription is ready for pickup. &amp;nbsp;With VoiceModel you can develop a notification system once and it will run on any &lt;a href=&quot;http://voxeo.com/glossary/what-is-voicexml/&quot; target=&quot;_blank&quot;&gt;VoiceXML compatible IVR&lt;/a&gt; or &lt;a href=&quot;https://www.tropo.com/home.jsp&quot; target=&quot;_blank&quot;&gt;Tropo&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
I personally find notification systems very useful. &amp;nbsp;I like being kept being informed on events like, my Amazon order was delivered, my flight was delayed, or my kid should be bringing home a report card today. This type of&amp;nbsp;notification&amp;nbsp;is beneficial, but I do not like SPAM. &amp;nbsp;Do not bombard my phone with sales and advertising. &amp;nbsp;Not only is this&amp;nbsp;annoying, it is illegal. Be sure to understand the &lt;a href=&quot;http://www.ecfr.gov/cgi-bin/text-idx?c=ecfr&amp;amp;rgn=div6&amp;amp;view=text&amp;amp;node=47:3.0.1.1.11.12&amp;amp;idno=47&quot; target=&quot;_blank&quot;&gt;Federal rules and regulations around notifications via the telephone&lt;/a&gt;&amp;nbsp;before developing a notification system,&amp;nbsp;or you could be slapped with a very large fine.&amp;nbsp;There, I warned you. &lt;br /&gt;
&lt;br /&gt;
Now that we have the legal issues out of the way lets see how you implement a notification application. VoiceModel has a new object/model called &lt;i&gt;Call&lt;/i&gt;. &amp;nbsp;&lt;i&gt;Call &lt;/i&gt;accepts as parameters the phone number to dial, the phone number the call is from that will show up in the Caller ID (optional), and the URI for the controller that &amp;nbsp;contains the voice application to play when the call is answered. &amp;nbsp;Here is what a simple application might look like.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:csharp&quot;&gt;    public class CallMeController : VoiceController
    {
        public override CallFlow BuildCallFlow()
        {
            string phoneNumber = ConfigurationManager.AppSettings[&quot;phoneNumber&quot;];
            string callerId = ConfigurationManager.AppSettings[&quot;callerId&quot;];
            string dialogUri = this.ApplicationUri + &quot;Outbound&quot;;
            CallFlow flow = new CallFlow();
            flow.AddState(ViewStateBuilder.Build(&quot;call&quot;, new Call(&quot;callMe&quot;, phoneNumber, callerId, dialogUri)), true);
            return flow;
        }
    }

&lt;/pre&gt;
&lt;br /&gt;
In this example I am getting the phone number to call and caller ID from configuration settings in the web.config. &amp;nbsp;The dialogUri is the explicit path for the MVC/VoiceModel controller that contains the voice application I want to play to the caller when they answer. &amp;nbsp;There is a new example project in the&lt;a href=&quot;http://voicemodel.codeplex.com/SourceControl/changeset/view/23962&quot; target=&quot;_blank&quot;&gt; source code &lt;/a&gt;called &lt;i&gt;OutboundCall &lt;/i&gt;that demonstrates how to implement this simple notification system.&lt;br /&gt;
&lt;br /&gt;
This simple example demonstrates the basics for outbound notification but is not very useful for a production application. &amp;nbsp;I am adding to the&amp;nbsp;Road Map&amp;nbsp;for VoiceModel a project that demonstrates how to manage a list of people to notify. &amp;nbsp;This can be challenging because it is a queue that has temporal information (time windows for notification so we do not call in the middle of the night) and information for retries on failed calls. &amp;nbsp;We are always looking for contributors if you want to tackle this interesting project. &amp;nbsp;Just &lt;a href=&quot;http://www.codeplex.com/site/users/view/kjunghans&quot; target=&quot;_blank&quot;&gt;contact me on CodePlex&lt;/a&gt; if you are interested.&lt;br /&gt;
&lt;br /&gt;
Another feature I would like to add for proactive notification is using a different voice application dependent upon whether a machine or a human answers. &amp;nbsp;If a machine answers (i.e. voice mail) then it does not make sense to have the voice application ask for&amp;nbsp;information&amp;nbsp;(ex: &quot;Would you like to continue getting updates on our progress on getting the power outage in your area fixed?&quot;) when the machine will not respond. &amp;nbsp;In this case you may want to play a different message that provides a phone number for them to dial for an inbound IVR application. &amp;nbsp;The challenge is that VoiceXML applications are pretty good at determining whether a machine or human has answered, whereas Tropo does not distinguish between the two. &amp;nbsp;This puts a kink in my vision of developing an application once and having it behave the same on a VoiceXML IVR as it does on Tropo. &amp;nbsp;And perhaps Twilio in future versions.&lt;br /&gt;
&lt;br /&gt;
One of the reasons that VoiceXML does much better at determining whether a human or machine answered is that the calls are initiated using&lt;a href=&quot;http://www.w3.org/TR/ccxml/&quot; target=&quot;_blank&quot;&gt; Call Control XML (CCXML)&lt;/a&gt;. &amp;nbsp;CCXML provide much better call control and call progress analysis. &amp;nbsp;Which brings up an important point when deploying VoiceModel notification systems. When configuring an application that uses VoiceXML for the voice application you need to configure the starting app as CCXML with the URL for the Controller that has the &lt;i&gt;Call &lt;/i&gt;object. For Tropo you configure it as any Tropo application , again using the URL for the Controller that has the &lt;i&gt;Call &lt;/i&gt;object.&lt;br /&gt;
&lt;br /&gt;
And how do we initiate the call since the application is not being triggered by an incoming phone call? &amp;nbsp;If you are using Tropo&#39;s development environment you first need to get permission from Voxeo Customer Support to make outbound calls from their system by creating a support ticket making the request. Once you have permission you go to where you defined your application in the &lt;a href=&quot;https://www.tropo.com/applications/&quot; target=&quot;_blank&quot;&gt;Tropo Development Web Site&lt;/a&gt; and there will be a section called &lt;i&gt;Outbound Tokens&lt;/i&gt;. &amp;nbsp;Click on the one that says &lt;i&gt;Voice &lt;/i&gt;and this will bring up a dialog that you click on the&amp;nbsp;&lt;i&gt;Launch Token&lt;/i&gt; button. &amp;nbsp;This will start your outbound application. &amp;nbsp;Voxeo Prophecy for VoiceXML works in much the same way when using their &lt;a href=&quot;http://evolution.voxeo.com/&quot; target=&quot;_blank&quot;&gt;development environment&lt;/a&gt;. This will work fine when you are testing. If you want to automate this process for production you will need to develop an application that makes HTTP requests that passes this token in. It is basically a REST API that is documented on their web sites.&lt;br /&gt;
&lt;br /&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
 SyntaxHighlighter.highlight();
&lt;/script&gt;</content><link rel='replies' type='application/atom+xml' href='http://kevin-junghans.blogspot.com/feeds/3519570020321040288/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kevin-junghans.blogspot.com/2013/03/create-proactive-notification.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2016746845209941562/posts/default/3519570020321040288'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2016746845209941562/posts/default/3519570020321040288'/><link rel='alternate' type='text/html' href='http://kevin-junghans.blogspot.com/2013/03/create-proactive-notification.html' title='Create Proactive Notification Applications with VoiceModel'/><author><name>Kevin Junghans</name><uri>http://www.blogger.com/profile/01125287678342544067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2016746845209941562.post-3702484777675919915</id><published>2013-03-08T14:42:00.001-05:00</published><updated>2018-07-26T14:55:18.970-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ASP.Net"/><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="MVC 4"/><category scheme="http://www.blogger.com/atom/ns#" term="security"/><category scheme="http://www.blogger.com/atom/ns#" term="SimpleMembership"/><title type='text'>Decoupling SimpleMembership From Your ASP.NET MVC Application</title><content type='html'>I recently came across a &lt;a href=&quot;http://stackoverflow.com/questions/15006532/simplemembership-anyone-made-it-n-tier-friendly/15162535#15162535&quot; target=&quot;_blank&quot;&gt;question in StackOverflow on making SimpleMembership &quot;N-Tier Friendly&quot;&lt;/a&gt;. &amp;nbsp;The author of the question correctly pointed out that the code generated by the Internet template tightly couples &lt;i&gt;SimpleMembership &lt;/i&gt;with the rest of the web application, peppering the application with code at the database level. What the author was really looking for was if anyone had taken the time to write &lt;i&gt;SimpleMembership &lt;/i&gt;as a&amp;nbsp;separate&amp;nbsp;layer that he could reuse. My answer was that &lt;a href=&quot;http://kevin-junghans.blogspot.com/2013/01/seeding-customizing-aspnet-mvc.html&quot; target=&quot;_blank&quot;&gt;&lt;i&gt;SimpleMembership &lt;/i&gt;was designed to be highly customizable&lt;/a&gt; and therefore any library written to decouple &lt;i&gt;SimpleMembership &lt;/i&gt;from the application would not be reusable. That being said I thought it would be a good exercise to provide an example of how you could go about writing a library that abstracts &lt;i&gt;SimpleMembership &lt;/i&gt;and has the features that we have covered so far in this blog, such as &lt;a href=&quot;http://kevin-junghans.blogspot.com/2013/02/adding-email-confirmation-to.html&quot; target=&quot;_blank&quot;&gt;email confirmation&lt;/a&gt; and&lt;a href=&quot;http://kevin-junghans.blogspot.com/2013/02/mixing-forms-authentication-basic.html&quot; target=&quot;_blank&quot;&gt; basic authentication&lt;/a&gt;. &amp;nbsp;And since I am making the source code available anyone can take this code as a starting point and customize it to their application requirements.&lt;br /&gt;
&lt;br /&gt;
I have put the VS 2012 projects for each tutorial on &lt;i&gt;SimpleMembership &lt;/i&gt;in &lt;a href=&quot;https://github.com/kjunghans/SimpleSecurity&quot; target=&quot;_blank&quot;&gt;GitHub &lt;/a&gt;where anyone can download them. &lt;br /&gt;
&lt;br /&gt;
So what did I mean when I stated that the template generated code peppers the application code with database specific information. &amp;nbsp;One example is in the initialization code for&amp;nbsp;&lt;i&gt;InitializeSimpleMembershipAttribute&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:csharp&quot;&gt;private class SimpleMembershipInitializer
{
    public SimpleMembershipInitializer()
    {
        Database.SetInitializer&amp;lt;userscontext&amp;gt;(null);

        try
        {
            using (var context = new UsersContext())
            {
                if (!context.Database.Exists())
                {
                    // Create the SimpleMembership database without Entity Framework migration schema
                    ((IObjectContextAdapter)context).ObjectContext.CreateDatabase();
                }
            }

            WebSecurity.InitializeDatabaseConnection(&quot;DefaultConnection&quot;, &quot;UserProfile&quot;, &quot;UserId&quot;, &quot;UserName&quot;, autoCreateTables: true);
        }
        catch (Exception ex)
        {
            throw new InvalidOperationException(&quot;The ASP.NET Simple Membership database could not be initialized. For more information, please see http://go.microsoft.com/fwlink/?LinkId=256588&quot;, ex);
        }
    }
}
&lt;/pre&gt;
&lt;br /&gt;
As you can see from this code &lt;i&gt;DbContext &lt;/i&gt;and other EF classes are called directly to setup initialization of the database. &amp;nbsp;When I write MVC applications I like to use several design patterns to encapsulate the database layer from the application domain. One is the &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ff649690.aspx&quot; target=&quot;_blank&quot;&gt;Repository Design Pattern,&lt;/a&gt; which&amp;nbsp;encapsulates which ORM we are using. This allows for easily swapping out EF for another ORM, and&amp;nbsp;for using&amp;nbsp;mock-ups&amp;nbsp;during unit testing. &amp;nbsp;And I usually use &lt;a href=&quot;http://msdn.microsoft.com/en-us/magazine/dd882510.aspx&quot; target=&quot;_blank&quot;&gt;Unit of Work Design Pattern &lt;/a&gt;to handle transactions. &amp;nbsp;With this in mind I created an assembly called &lt;i&gt;SimpleSecurity &lt;/i&gt;which encapsulates &lt;i&gt;SimpleMembership &lt;/i&gt;using these design patterns. If you look at the &lt;i&gt;SimpleSecurity &lt;/i&gt;source code you will see a Repositories folder/namespace that contains a repository for &lt;i&gt;UserProfile &lt;/i&gt;and a unit of work class. We will add more repositories in later posts that will add more functionality for &lt;i&gt;SimpleSecurity&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;SimpleSecurity &lt;/i&gt;is an application layer that encapsulates the methods in &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/webmatrix.webdata.websecurity(v=vs.111).aspx&quot; target=&quot;_blank&quot;&gt;&lt;i&gt;WebSecurity&amp;nbsp;&lt;/i&gt;&lt;/a&gt;as well as access to the &lt;i&gt;UserProfile&lt;/i&gt;. &amp;nbsp;So what does our&amp;nbsp;initialization process look like when using &lt;i&gt;SimpleSecurity&lt;/i&gt;. We remove the use of &amp;nbsp;&lt;i&gt;InitializeSimpleMembershipAttribute &lt;/i&gt;and put it in the &lt;i&gt;Global.asax Application_Start&lt;/i&gt; method&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:csharp; highlight:10&quot;&gt;protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();

    WebApiConfig.Register(GlobalConfiguration.Configuration);
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);
    AuthConfig.RegisterAuth();
    WebSecurity.Register();
}

&lt;/pre&gt;
As you can see from this example you just call &lt;i&gt;WebSecurity.Register&lt;/i&gt;. &lt;i&gt;SimpleSecurity &lt;/i&gt;uses the same class name of &lt;i&gt;WebSecurity &lt;/i&gt;as &lt;i&gt;WebMatrix &lt;/i&gt;so you just have to change the uses clauses to &lt;i&gt;SimpleSecurity &lt;/i&gt;and remove &lt;i&gt;WebMatrix &lt;/i&gt;and most of the code will work the same as in your original app. So here are the steps for using &lt;i&gt;SimpleSecurity&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;Include SimpleSecurity in your MVC project&lt;/li&gt;
&lt;li&gt;Remove all uses statements for &lt;i&gt;WebMatrix &lt;/i&gt;and replace them with &lt;i&gt;SimpleSecurity&lt;/i&gt;.&lt;/li&gt;
&lt;li&gt;Remove &amp;nbsp;&lt;i&gt;InitializeSimpleMembershipAttribute.cs&lt;/i&gt; from your MVC project.&lt;/li&gt;
&lt;li&gt;Remove the reference to&amp;nbsp;&lt;i&gt;InitializeSimpleMembershipAttribute&amp;nbsp;&lt;/i&gt;in the &lt;i&gt;AccountConroller&lt;/i&gt;.&lt;/li&gt;
&lt;li&gt;Add &lt;i&gt;WebSecurity.Register()&lt;/i&gt; to the &lt;i&gt;Global.asax&lt;/i&gt;, as shown above.&lt;/li&gt;
&lt;li&gt;Remove &lt;i&gt;UsersContext &lt;/i&gt;and &lt;i&gt;UserProfile &lt;/i&gt;classes from &lt;i&gt;AccountModels.cs&lt;/i&gt;.&lt;/li&gt;
&lt;li&gt;Remove all references to &lt;i&gt;UsersContext &lt;/i&gt;in the &lt;i&gt;AccountController &lt;/i&gt;and replace them with a &lt;i&gt;SimpleSecurity.WebSecurity&lt;/i&gt; method.&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;
&lt;br /&gt;
On the last item you will find code like this in the &lt;i&gt;AccountController&lt;/i&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:csharp&quot;&gt;   // Insert a new user into the database
    using (UsersContext db = new UsersContext())
    {
        UserProfile user = db.UserProfiles.FirstOrDefault(u =&amp;gt; u.UserName.ToLower() == model.UserName.ToLower());
        // Check if user already exists
        if (user == null)
        {
            // Insert name into the profile table
            db.UserProfiles.Add(new UserProfile { UserName = model.UserName });
            db.SaveChanges();

            OAuthWebSecurity.CreateOrUpdateAccount(provider, providerUserId, model.UserName);
            OAuthWebSecurity.Login(provider, providerUserId, createPersistentCookie: false);

            return RedirectToLocal(returnUrl);
        }
        else
        {
            ModelState.AddModelError(&quot;UserName&quot;, &quot;User name already exists. Please enter a different user name.&quot;);
        }
     }
&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
Which now becomes this.
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:csharp&quot;&gt;        try
        {
            WebSecurity.CreateUser(new UserProfile() 
                { UserName = model.UserName });
            OAuthWebSecurity.CreateOrUpdateAccount(provider, providerUserId, model.UserName);
            OAuthWebSecurity.Login(provider, providerUserId, createPersistentCookie: false);
        }
        catch (Exception ex)
        {
            ModelState.AddModelError(&quot;UserName&quot;, &quot;User name already exists. Please enter a different user name.&quot;);
        }

&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
And when we need to get information on the current user it will look like this.
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:csharp&quot;&gt;  var user = WebSecurity.GetCurrentUser();
  ViewBag.Email = user.Email;

&lt;/pre&gt;
&lt;br /&gt;
Now we have a clean layer that decouples our security data from the rest of the MVC application. I will use this as a basis for future enhancements to &lt;i&gt;SimpleMembership &lt;/i&gt;going forward. &amp;nbsp; For example, I &lt;a href=&quot;http://kevin-junghans.blogspot.com/2013/03/trouble-deleting-users-in.html&quot; target=&quot;_blank&quot;&gt;discussed a bug when deleting users when using &lt;i&gt;WebMatrix.WebSecurity&lt;/i&gt;&lt;/a&gt;. Now we can implement a new version of &lt;i&gt;DeleteUser &lt;/i&gt;in &lt;i&gt;SimpleSecurity.WebSecurity&lt;/i&gt; that fixes this issue. &amp;nbsp;Watch this blog for further enhancements to &lt;i&gt;SimpleSecurity&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
 SyntaxHighlighter.highlight();
&lt;/script&gt;</content><link rel='replies' type='application/atom+xml' href='http://kevin-junghans.blogspot.com/feeds/3702484777675919915/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kevin-junghans.blogspot.com/2013/03/decoupling-simplemembership-from-your.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2016746845209941562/posts/default/3702484777675919915'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2016746845209941562/posts/default/3702484777675919915'/><link rel='alternate' type='text/html' href='http://kevin-junghans.blogspot.com/2013/03/decoupling-simplemembership-from-your.html' title='Decoupling SimpleMembership From Your ASP.NET MVC Application'/><author><name>Kevin Junghans</name><uri>http://www.blogger.com/profile/01125287678342544067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2016746845209941562.post-5647287227853773417</id><published>2013-03-06T16:08:00.000-05:00</published><updated>2013-03-06T16:08:07.047-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ASP.Net"/><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="MVC 4"/><category scheme="http://www.blogger.com/atom/ns#" term="security"/><category scheme="http://www.blogger.com/atom/ns#" term="SimpleMembership"/><title type='text'>Trouble Deleting Users in SimpleMembership</title><content type='html'>I came across a &lt;a href=&quot;http://stackoverflow.com/questions/15232995/membership-deleteuser-is-not-deleting-all-related-rows-of-the-user/15234347#comment21504314_15234347&quot; target=&quot;_blank&quot;&gt;question in StackOverflow&lt;/a&gt; the other day where someone was having trouble deleting a user in the SimpleMembership provider that is now the default provider in ASP.NET MVC 4 Internet Applications. &amp;nbsp;The problem he was having was that when he called&amp;nbsp;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/webmatrix.webdata.simplemembershipprovider.deleteuser%28v=vs.111%29.aspx&quot; target=&quot;_blank&quot;&gt;SimpleMembershipProvider.DeleteUser&lt;/a&gt; it was deleting the data in the &lt;b&gt;UserProfile &lt;/b&gt;table and not in the&amp;nbsp;&lt;b&gt;webpages_Membership&lt;/b&gt; table. First a little bit on what these two tables are about.&lt;br /&gt;
&lt;br /&gt;
SimpleMembership is designed to put the user information in these two tables, which have a one-to-zero-or-one relationship. &amp;nbsp;The &lt;b&gt;UserProfile &lt;/b&gt;table has a unique &lt;b&gt;UserId &lt;/b&gt;and a &lt;b&gt;UserName&lt;/b&gt;, and &lt;a href=&quot;http://kevin-junghans.blogspot.com/2013/01/seeding-customizing-aspnet-mvc.html&quot; target=&quot;_blank&quot;&gt;UserProfile can be customized by the developer&lt;/a&gt;. &amp;nbsp;This UserId is a foreign key for the webpages_Membership table, which contains the password and other security information in it. &amp;nbsp;The reason for keeping information in these table&amp;nbsp;separate&amp;nbsp;is that the data in webpages_Membership is not required if OAuth is being used. If OAuth is being used then the password and other security details will be on another system.&lt;br /&gt;
&lt;br /&gt;
Now back to the problem. I found it hard to believe that using &lt;b&gt;DeleteUser &lt;/b&gt;did not remove both tables because here is what the documentation says.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;color: #2a2a2a; font-family: &#39;Segoe UI&#39;, &#39;Lucida Grande&#39;, Verdana, Arial, Helvetica, sans-serif; font-size: 12px; line-height: 18px;&quot;&gt;This method deletes the entry in the membership account table (by default, webpages_Membership). If&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;parameter&quot; style=&quot;color: #2a2a2a; font-family: &#39;Segoe UI&#39;, &#39;Lucida Grande&#39;, Verdana, Arial, Helvetica, sans-serif; font-size: 12px; font-style: italic; line-height: 18px;&quot;&gt;deleteAllRelatedData&lt;/span&gt;&lt;span style=&quot;color: #2a2a2a; font-family: &#39;Segoe UI&#39;, &#39;Lucida Grande&#39;, Verdana, Arial, Helvetica, sans-serif; font-size: 12px; line-height: 18px;&quot;&gt;&amp;nbsp;is true, all user data that is stored in the user table is also deleted.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
So here is the quick and dirty test I ran.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:csharp&quot;&gt;var roles = (SimpleRoleProvider)Roles.Provider;
var membership = (SimpleMembershipProvider)Membership.Provider;

if (membership.GetUser(&quot;test&quot;, false) == null)
{
    membership.CreateUserAndAccount(&quot;test&quot;, &quot;test&quot;);
}

bool wasDeleted = membership.DeleteUser(&quot;test&quot;, true);
&lt;/pre&gt;
&lt;br /&gt;
I stepped through with the debugger after the &lt;b&gt;CreateUserAndAccount&lt;/b&gt; and saw an entry for the user in both tables. Then I stepped over &lt;b&gt;DeleteUser &lt;/b&gt;and checked the database again. The entry in &lt;b&gt;UserProfile &lt;/b&gt;was gone but the one in &lt;b&gt;webpages_Membership &lt;/b&gt;was still there. &amp;nbsp;This was a far cry from what the documentation described as the behavior for this method and verified what the person asking the question in StackOverflow observed.&lt;br /&gt;
&lt;br /&gt;
So I thought I would try something else to see if I could come up with a workaround for this issue. Here is the code I tried.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:csharp&quot;&gt;var roles = (SimpleRoleProvider)Roles.Provider;
var membership = (SimpleMembershipProvider)Membership.Provider;

if (membership.GetUser(&quot;test&quot;, false) == null)
{
    membership.CreateUserAndAccount(&quot;test&quot;, &quot;test&quot;);
}

bool wasDeleted = membership.DeleteAccount(&quot;test&quot;);

wasDeleted = membership.DeleteUser(&quot;test&quot;, true);
&lt;/pre&gt;
&lt;br /&gt;
Now when I stepped through with the debugger when I hit &lt;b&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/webmatrix.webdata.simplemembershipprovider.deleteaccount(v=vs.111).aspx&quot; target=&quot;_blank&quot;&gt;DeleteAccount &lt;/a&gt;&lt;/b&gt;the entry from &lt;b&gt;webpages_Membership &lt;/b&gt;was removed and then when I hit &lt;b&gt;DeleteUser &lt;/b&gt;the entry in &lt;b&gt;UserProfile &lt;/b&gt;was removed. Now we do not have any orphans hanging around. &amp;nbsp;Not sure if and when Microsoft will fix this bug but at least there is a workaround.&lt;br /&gt;
&lt;br /&gt;
I should also point out that if you have a user mapped to roles using &lt;b&gt;DeleteUser &lt;/b&gt;will throw a foreign key exception. You have to remove any mapped roles before you can use it.&lt;br /&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
 SyntaxHighlighter.highlight();
&lt;/script&gt;</content><link rel='replies' type='application/atom+xml' href='http://kevin-junghans.blogspot.com/feeds/5647287227853773417/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kevin-junghans.blogspot.com/2013/03/trouble-deleting-users-in.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2016746845209941562/posts/default/5647287227853773417'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2016746845209941562/posts/default/5647287227853773417'/><link rel='alternate' type='text/html' href='http://kevin-junghans.blogspot.com/2013/03/trouble-deleting-users-in.html' title='Trouble Deleting Users in SimpleMembership'/><author><name>Kevin Junghans</name><uri>http://www.blogger.com/profile/01125287678342544067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>