Showing posts with label Security. Show all posts
Showing posts with label Security. Show all posts

2012-08-27

SimpleMembershipProvider ... HUH?!?!

UPDATE (2012-08-30):
John Galloway of Microsoft has put together a very helpful insight into Simple Membership Provider at http://bit.ly/PtkPN1 So, if any of you is still looking for some background information or the basic idea behind Simple Membership Provider, have a go and read his blog post. Thanks John!
Hi,
Yesterday I was playing around with the new Visual Studio 2012 and MVC4.
So far I am impressed with Visual Studio and asp.net 4.5 but my yesterday's adventure made me go HUH?!?!

Well, I created a new MVC4-Application. That should not be too hard, just hit File -> New -> Project and select Web -> MVC 4 Application.

So far so good, a new application was created and ready to run. Then to use the default 'localDB' file, I followed what I had learned to work fine with the previous release candidates and installed the corresponding Default Membership Provider package via Nu-Get (based on Scott Hanselman - Introducing System.Web.Providers), which worked well in some previous release candidate of vs2012
install-package System.Web.Providers.localDB
After the installation was finished I ran the application and hit 'Register' so the application would create the corresponding database-file. Which it did and the server explorer even listed it correctly. Then I entered the credentials of a new testuser 'tommy', 'test123$', 'test123$' and clicked 'Register' and then the application gave up:


Zeile 80:                 try
Zeile 81:                 {
Zeile 82:                     WebSecurity.CreateUserAndAccount(model.UserName, model.Password);
Zeile 83:                     WebSecurity.Login(model.UserName, model.Password);
Zeile 84:                     return RedirectToAction("Index", "Home");

Quelldatei: c:\Users\igambin\Documents\Visual Studio 2012\Projects\MvcApplication6\MvcApplication6\Controllers\AccountController.cs    Zeile: 82
At some point before the final release of Visual Studio 2012, Microsoft seems to have decided to use the SimpleMembershipProvider (see Matthew M. Osborne - Using SimpleMembership With ASP.NET WebPages) by Default instead of the DefaultMembershipProvider.
Basically and in relation to Azure or Web Pages that might be helpful and even advantageous, but for someone used to the old MembershipProviders at first it seems a strange decision. I mean, I loved the MembershipProviders as they represented a full-fledged and secure means of user/role/membership data management which Visual Studio even offered a built in solution to manage.

Well, that built-in management won't work with SimpleMembership (at least not yet) but I wanted at least to get the "NEW Default" MembershipProvider up and running. So I decided instead of using localDB I would want to use SqlServer Compact Edition. So I installed that
install-package sqlservercompact
And again based on ScottHa's BlogPost mentioned above, I added a corresponding "ConnectionString" to my web.config:
At that moment I realized: "hey, there is nothing that relates SimpleMembership to use that new ConnectionString". Therefore I started looking into the SimpleMembership files and did find the AccountModel.cs which named the connection string in its constructor
public class UsersContext : DbContext
{
    public UsersContext()
        : base("Sql_CE")
    {
    }
    public DbSet UserProfiles { get; set; }
}
where I put my SqlServerCompact ConnectionString so SimpleMembership would use the right file.

Yes, at that point I was a bit surprised that the ConnectionString was hardcoded into the model file. The old Membership Providers had that kind of configuration done in the web.config file. Actually I think I would have preferred the old way to do it. Well, again I tried to start my application and add a new user and again the application stroke back


Zeile 39: }
Zeile 40:
Zeile 41: WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);Zeile 42: }
Zeile 43: catch (Exception ex)

Quelldatei: c:\Users\igambin\Documents\Visual Studio 2012\Projects\MvcApplication5\MvcApplication5\Filters\InitializeSimpleMembershipAttribute.cs    Zeile: 41             


Not only is the ConnectionString hardcoded into SimpleMembership once, it indeed has been done twice!

I modified that line to also use the connectionString I defined in my web.config. At that point the application worked and the SimpleMembership Provider provided what it should.

Still... I really miss hitting PROJECT->ASP.NET Configuration to just open up the Asp.net configuration web-site where I would manage my users and roles and user-role memberships.




2012-03-21

ASP.Net Default Password Hash (+Salt)

Today I played around with custom user controls so I wondered if I could create my own login control, that would allow me to check credentials against the built-in ASP.net security mechanisms. The included Table structure is easy enough to understand, but it took me a while to find out how to apply salt and hashing algorithms to the entered user password to get the same hash that the ASP.net security mechanisms generate. Just to not forget it or to whoever might need it:


        public static string EncodePassword(string pass, string saltBase64)
        {
            byte[] bytes = Encoding.Unicode.GetBytes(pass);
            byte[] src = Convert.FromBase64String(saltBase64);
 
            byte[] dst = new byte[src.Length + bytes.Length];
            System.Buffer.BlockCopy(src, 0, dst, 0, src.Length);
            System.Buffer.BlockCopy(bytes, 0, dst, src.Length, bytes.Length);
            HashAlgorithm algorithm = HashAlgorithm.Create("SHA1");
 
            byte[] inArray = algorithm.ComputeHash(dst);
            return Convert.ToBase64String(inArray);
        }


And if you have to create a new Salt, just use:


        public string CreateSalt(int saltLength)
        {
            //Create and populate random byte array
            byte[] randomArray = new byte[length];
            string randomString;
 
            //Create random salt and convert to string
            RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
            rng.GetBytes(randomArray);
            randomString = Convert.ToBase64String(randomArray);
            return randomString;
        }


Resources: forums.asp.netPeter Stathakos Blog