Migrating asp.net web site breaks Membership Provider - asp.net

I have a asp.net web site that was developed on the .Net Framework v2 connecting to sql server 2000. I am trying to migrate it to a new server that has the .Net Framework v3.5 on it along with sql server 2008. I backed up the database and restored it to the new database server. I moved the web site and updated the web.config. Now however I cannot login to the website. I ran sql profiler to see what was going on and this is the stored proc that gets run when I attempt to login.
exec dbo.aspnet_Membership_GetPasswordWithFormat #ApplicationName=N'dev',
#UserName=N'AffiliateBob', #UpdateLastLoginActivityDate=1,
#CurrentTimeUtc='2009-10-26 20:43:23.7130000'
Notice the format of the #CurrentTimeUtc parameter. When I put this into sql management studio and run it I get the following error message.
Msg 8114, Level 16, State 1, Procedure aspnet_Membership_GetPasswordWithFormat, Line 0
Error converting data type varchar to datetime.
Here is the membership section from my web.config.
<membership>
<providers>
<clear/>
<add name="AspNetSqlMembershipProvider"
type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
connectionStringName="LocalSqlServer"
enablePasswordRetrieval="false"
enablePasswordReset="true"
requiresQuestionAndAnswer="false"
requiresUniqueEmail="true"
passwordFormat="Hashed"
maxInvalidPasswordAttempts="999"
minRequiredPasswordLength="6"
minRequiredNonalphanumericCharacters="0"
passwordAttemptWindow="999"
passwordStrengthRegularExpression=""
applicationName="dev"/>
</providers>
</membership>

This turned out to be a web.config issue. That I resolved by creating a new clean web.config file and adding sections from the old web.config.

Does it work OK if you change the date to 2009-10-10? If so, you have a language/locale issue. ASP.NET is sending the date parameter in MM/DD and SQL Server is expecting DD/MM or vice-versa. Check this setting in ASP.NET and for your SQL Server login.

This may not be the best solution in some cases, but this ended up solving my issue:
http://forums.asp.net/t/1398826.aspx/1
I'd originally tried to dig into the Membership Provider stored procs and start moving all of the DateTime's over to DateTime2's, but I'm sure you can imagine the can of worms that opens up. Either way, the DateTime conversion issue is a good one to know about.

Related

Wiring up ASP.NET Web Application using Forms Authentication with SqlMembership Provider on Azure

I'm experimenting with the Microsoft Azure portal in order to see how my legacy application performs with the least amount of rewrite. Authentication is a problem.
Background: this ASP.NET web application currently uses the SqlMembership Provider for Users, Roles, Profiles and Personalization. Yep, there has been a lot of blogging about the ASP.NET Identity, Simple Membership, Universal Providers and that the asp.net SqlMembership Provider is being phased out. But, if possible I'd still rather use the legacy asp.net membership on Azure.
Currently, I am able to publish my VS.NET 2013 solution to Azure but I am not able to login. As soon as I navigate to the url, it auto-logs me in as the Azure Portal user. It almost appears that Windows Authentication is active, rather than forms. Here's how I got here:
I created the sql membership tables on Sql Azure using special Azure-friendly scripts for Sql Azure (here: https://support.microsoft.com/kb/2006191).
However, when I run my application on the azure site vs. when I run it locally I see different behavior. On azure a different authentication mechanism takes hold: first, I'm prompted to login with my organizational ID (this is my msdn email), then after I enter my login for Azure, I automatically get logged into my application as live.com#myazureid#domain.com and I am not redirected to default.aspx but login.aspx and none of the web.sitemap menus appear other than the ones available to non-authenticated users. I also created a second user in the portal jeff#mydomain.onmicrosoft.com and I am prompted to login thru live then I am autologged into the application. Basically it acts like windows authentication is active, not forms auth. (Clarification: I found out later that this behavior is Azure Active Directory.)
In contrast, when my application runs locally (vs.NET 2013) with my connection strings pointing to the same sql azure data source (the membership tables) I login as I'd expect: I enter my membership username/password and I see my default page and pages tied to my roles are accessible, the user exists in users table, etc.. Obviously my local runtime environment and azure are different and it seems that Azure is somehow overriding my web.config provider settings and using its own mechanism.
My web.config:
<authentication mode="Forms">
<forms cookieless="UseCookies" defaultUrl="~/Default.aspx" loginUrl="~/PagesAnon/userLogin.aspx" requireSSL="false" slidingExpiration="true" timeout="45" />
</authentication>
<membership defaultProvider="AspNetSqlMembershipProvider" userIsOnlineTimeWindow="2">
<providers>
<clear />
<remove name="AspNetSqlMembershipProvider" />
<add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="LocalSqlServer" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="true" applicationName="/" requiresUniqueEmail="false" passwordFormat="Hashed" maxInvalidPasswordAttempts="4" minRequiredPasswordLength="7" minRequiredNonalphanumericCharacters="1" passwordAttemptWindow="10" passwordStrengthRegularExpression="" />
</providers>
</membership>
<roleManager defaultProvider="AspNetSqlRoleProvider" enabled="true" cacheRolesInCookie="true">
<providers>
<clear />
<remove name="AspNetSqlRoleProvider" />
<add name="AspNetSqlRoleProvider" connectionStringName="LocalSqlServer" applicationName="/" type="System.Web.Security.SqlRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</providers>
</roleManager>
Thanks to Simon W above, I found my problem. In the Azure Portal, there is a setting that controls "Azure Websites Authentication / Authorization". Its found under Websites, then Configure, then scroll down a bit to "Azure Websites Authentication / Authorization". In my case there was an entry there: my website was tied into the "Directory" for my account and the "application" was set to my "tenant" (I think that's the Azure term).
To fix this, I simply removed the entry in the portal and I am able to login to my web application perfectly. Forms authentication wired up to Membership is working as I'd expect.
I believe that I published the original website using VS.NET 2013 Publish (using Server Explorer with the Azure SDK tools installed) and maybe there is a default setting that enables Azure AD in that scenario. I won't know until I retrace my steps and confirm this later. When I create a new website using the Portal, it does not default to this scheme.
Simon, I don't know how to give you credit for the answer... you basically got my head pointed in the right direction (just the use of "Azure AD authentication" got be googling the right terms) and facilitated the fix.

Cant see my membership provider in aspnet tools

i am just creating a aspnet MVC 4 basic application with custom membership provider.
I follow these steps:
1) Create the membership tables in the Sql Server 2008 using aspnetregsql.exe
So i have the custom membership tables like:
aspnet_Users
aspnet_Membership
aspnet_Roles
...
2) Added a connection string refering to this database.
3) Added a provider in my web.config file inside the membership section:
<providers>
<clear />
<add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider"
connectionStringName="primecontrol" enablePasswordRetrieval="false"
enablePasswordReset="true" requiresQuestionAndAnswer="false"
requiresUniqueEmail="false" maxInvalidPasswordAttempts="5"
minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0"
passwordAttemptWindow="10" applicationName="/" />
So, when I run the ASP.NET configuration Tools and go to test my provider connection, it says that i dont create any providers.
But if i create a new user for example, it creates another tables in my database without the 'aspnet' prefix.
Whats going on?
i am just creating a aspnet MVC 4 basic application with custom
membership provider.
In the web.config, I do not see declaring custom membership provider.
It should be like -
<membership defaultProvider="CustomProvider">
<providers>
<clear/>
<add name="CustomProvider"
type="YourNamespace.YourMembershipProvider, YourNamespace"
... />
</providers>
</membership>
If you using ASP.Net MVC 4, you want to use new ASP.NET Universal Providers which is basically a newer version of Legacy Membership Provider that you are using.
ASP.NET Universal Providers uses Entity Framework Code First which is a lot cleaner compare to store procedures.
If you want to latest Membership, you might want to try ASP.NET Identity. Note: Identity is not backward compatible with Legacy Membership Provider.

Membership.ValidateUser works in 1 project fails in the other

I have a simple CLI app to create/update/delete users of an SqlMembershipProvider. It works, and I can validate just fine from the CLI app.
As soon as I try to do it from the related asp.net app, however, it fails. I've literally copy/pasted the relevant web.conf/app.config sections, so I have no clue why it's failing.
<machineKey validationKey="C94FA3782AAF21E932CAA92DC2A0641951E3A76E50DD25B19C627BA01E259C6CBC7839A7803A59EF3BF855152369A6AB10CC259513BE7ACA4E842B962FD1D8A4"
decryptionKey="2EA6D270AD94361ECFDCED5070D76FD67D9A147FEEBC8388FE9B73B450A04560"
validation="SHA1"
decryption="AES" />
<membership defaultProvider="MembershipProvider">
<providers>
<add name="MembershipProvider" type="System.Web.Security.SqlMembershipProvider"
connectionStringName="ApplicationServices"
enablePasswordRetrieval="false"
enablePasswordReset="true"
requiresQuestionAndAnswer="false"
requiresUniqueEmail="false"
maxInvalidPasswordAttempts="5"
minRequiredPasswordLength="1"
minRequiredNonalphanumericCharacters="0"
passwordAttemptWindow="10"
passwordStrengthRegularExpression=""/>
</providers>
</membership>
This is in both the web.config and app.config, can someone explain why this will validate in the CLI project and not the asp.net project?
And to be clear, here is the code that isn't validationg
Membership.ValidateUser("fake", "fake") // actual test un/pwd combo
I've verified that the un/pwd is in fact correct.
Without knowing anything else about you applications, it seems that the most likely issue is the applicationName attribute in the membership/providers/add node in the config files. See http://msdn.microsoft.com/en-us/library/system.web.security.membership.applicationname.aspx
These applications are probably defaulting to separate application names/identifiers. So when you attempt to login through the web app the provider only sees access granted to the CLI app. The CLI app may not have access to the web root or virtual path info (with no http context) to create a default name so it is probably defaulting to something different than your web app applicationName.
Look at this link for a good explanation: http://weblogs.asp.net/scottgu/archive/2006/04/22/Always-set-the-_2200_applicationName_2200_-property-when-configuring-ASP.NET-2.0-Membership-and-other-Providers.aspx
You can handle this in two ways:
Try setting the applicationName to the same string in both configurations.
OR
Ensure that there are two entries for the user "fake" in the aspnet_Membership table. One for the CLI app and one for the Web app. You should find the applicationID for each application listed in the aspnet_Application table.
Here is another reference where someone used the SqlMembershipProvider outside of an asp.net app: http://mdrasel.wordpress.com/2011/02/01/asp-net-membership-provider-outside-of-web-application/. Note the use of the applicationName attribute.

MongoDB Membership Provider on AppHarbor

I have an application on AppHarbor, and I've finally gotten it to work. One thing that's eluded me though is getting my Membership provider to work. I'm using MongoLab for my database, and it works fine with the rest of my application. When, I I try to use Membership, I get this error:
Unable to connect to server localhost:27017: No connection could be made because the target machine actively refused it 127.0.0.1:27017.
And the offending line is in web.config:
<add name="MongoDBMembershipProvider" type="MongoDB.Web.Providers.MongoDBMembershipProvider"....
Could someone please shed some light on my situation?
As friism mentions, you need some code to read the connectionString from an appSetting. Thankfully osuritz has already done the work in a fork of MongoDB.Web on github.
You will need to download the above fork, build & change your existing dll reference to use the new dll.
Then...
change your config:
<appSettings>
<add key="MONGOLAB_URL" value="mongodb://localhost/ASPNETDB"/>
</appSettings>
... the above value will get replaced by appharbor/mongolab (and if you have other parts of the app that work, then this is correct)
<providers>
<clear />
<add name="MongoDBMembershipProvider" type="MongoDB.Web.Providers.MongoDBMembershipProvider"
applicationName="/" appSettingsConnectionStringKey="MONGOLAB_URL" collection="Users"
enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false"
maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" />
</providers>
So in the above config, it has the appSettingsConnectionStringKey parameter. The code within the customised provider, reads the appSettingsConnectionStringKey value 'MONGOLAB_URL' and then uses that to read the ConfigurationManager.AppSettings["MONGOLAB_URL"] and it obviously, MUST match the appsetting Key name above.
In the <membership defaultProvider="MongoMember"><providers><add connectionStringName="foo"> you probably need to specify the name of the connectionstring that has you MongoLab connection. Unfortunately, that's not inserted in the connectionstrings element, it's in appSettings. You should probably figure out some way to get the provider to read the connectionstring out of appSettings.
Would suggest to use this project for your purpose http://extmongomembership.codeplex.com/. It supports using of AppHarbor out-of-the-box.
Just need to add useAppHarbor="true" to provider settings as written here https://extmongomembership.codeplex.com/wikipage?title=AppHarbor%20Integration&referringTitle=Documentation
Note: This is port of new Membership Provider that was presented in ASP.NET MVC4

Using one Asp.net Membership database with multiple applications Single Sign On

I have two asp.net applications on one IIS server and I would like to use the same back end asp_security database and membership provider. I've read that all I have to do is reference the same application name in both web configs as I'm doing now, but I must be doing something wrong
In each applications web.config I have this section.
<membership>
<providers>
<clear/>
<add name="AspNetSqlMembershipProvider"
type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
connectionStringName="membership"
enablePasswordRetrieval="false"
enablePasswordReset="true"
requiresQuestionAndAnswer="false"
applicationName="/"
requiresUniqueEmail="false"
minRequiredPasswordLength="5"
minRequiredNonalphanumericCharacters="0"
passwordFormat="Hashed"
maxInvalidPasswordAttempts="5"
passwordAttemptWindow="10"
passwordStrengthRegularExpression=""
/>
</providers>
</membership>
When I log in from application A and browse to application B application B doesn't seem to know anything about me or my credentials from application A. Anyone have any ideas what I'm doing incorrectly?
Just for closure sake I will answer how I did achieved the goal of what my original question meant to ask for.
I had two asp.net applications on one IIS server. It was my goal to make it so when user logged onto app1 their user credentials would be available in app2. Configuring the asp.net membership provider is only one step of what I was looking for. Even if both apps were using the same back end database and provider I still wouldn't be authenticated when I hit app2. What I was looking for was a Single Sign On solution.
Once you have both apps pointing at your asp_membership database by placing the following in the system.web section of your web config
<authentication mode="Forms" />
<membership>
<providers>
<clear/>
<add name="AspNetSqlMembershipProvider"
type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
connectionStringName="membership"
applicationName="/"
/>
</providers>
</membership>
<roleManager enabled="true" />
make sure both have the same applicationname property set.
I was using IIS 6 so I configured it to autogenerate a machine key for both applications. Because both of these applications live on the same machine the key would be identical, this is the critical part to making the SSO work. After setting up IIS the following was added to my web.config
<machineKey decryptionKey="AutoGenerate" validation="SHA1" validationKey="AutoGenerate" />
That was all there was to it. Once that was done I could log into app1 and then browse to app2 and keep my security credentials.
Thanks for the push in the right direction.
If my understanding serves me correctly, the users authentication credentails are stored within the HTTP context of each application. So switching between the two applications will not automatically authenticate the user, since a new context will be created when you switch to app B.
What I believe may the correct approach would be to use the DefaultCredentials (or UseDefaultCredentials property to True) of the current user prior to switching to app B.
When you say switch what do you mean eg. open a different browser window and access app B or request a page from appB from appA?

Resources