|
Contents
Introduction
As I started to work on a new AJAX-enabled website, I looked around for a MySQL implementation of the ASP.NET 2.0 membership provider. To my amazement, I couldn't find anything. So I decided to do my own implementation. After a few days of dev work, on and off, I found that I hadn't only implemented the membership provider but also the roles provider, site map provider and personalization provider.
All the providers inherit from the generic providers from Microsoft.
[^]
Using the Code
Using the providers is really easy.
-
Create a new database on your MySQL server, e.g. SimpleProviders.
-
Execute the following SQL statement on the newly created database.
CREATE TABLE `personalization` (
`username` varchar(255) default NULL,
`path` varchar(255) default NULL,
`applicationname` varchar(255) default NULL,
`personalizationblob` blob
);
CREATE TABLE `profiles` (
`UniqueID` int(8) NOT NULL auto_increment,
`Username` varchar(255) NOT NULL default '',
`ApplicationName` varchar(255) NOT NULL default '',
`IsAnonymous` tinyint(1) default '0',
`LastActivityDate` datetime default NULL,
`LastUpdatedDate` datetime default NULL,
PRIMARY KEY (`UniqueID`),
UNIQUE KEY `PKProfiles` (`Username`,`ApplicationName`),
UNIQUE KEY `PKID` (`UniqueID`)
);
CREATE TABLE `roles` (
`Rolename` varchar(255) NOT NULL default '',
`ApplicationName` varchar(255) NOT NULL default '',
PRIMARY KEY (`Rolename`,`ApplicationName`)
);
CREATE TABLE `sitemap` (
`ID` int(11) NOT NULL auto_increment,
`ApplicationName` varchar(255) NOT NULL default '',
`Title` varchar(255) default NULL,
`Description` text,
`Url` text,
`Roles` text,
`Parent` int(11) default NULL,
PRIMARY KEY (`ID`)
);
CREATE TABLE `users` (
`PKID` varchar(255) NOT NULL default '',
`Username` varchar(255) NOT NULL default '',
`ApplicationName` varchar(255) NOT NULL default '',
`Email` varchar(128) default NULL,
`Comment` varchar(255) default NULL,
`Password` varchar(128) NOT NULL default '',
`FailedPasswordAttemptWindowStart` datetime default NULL,
`PasswordQuestion` varchar(255) default NULL,
`IsLockedOut` tinyint(1) default '0',
`PasswordAnswer` varchar(255) default NULL,
`FailedPasswordAnswerAttemptCount` int(8) default '0',
`FailedPasswordAttemptCount` int(8) default '0',
`IsApproved` tinyint(1) NOT NULL default '0',
`FailedPasswordAnswerAttemptWindowStart` datetime default NULL,
`LastActivityDate` datetime default NULL,
`IsOnLine` tinyint(1) default '0',
`CreationDate` datetime default NULL,
`LastPasswordChangedDate` datetime default NULL,
`LastLockedOutDate` datetime default NULL,
`LastLoginDate` datetime default NULL,
PRIMARY KEY (`PKID`),
UNIQUE KEY `PKID` (`PKID`),
KEY `PKID_2` (`PKID`),
KEY `usr` (`Username`)
);
CREATE TABLE `usersinroles` (
`Username` varchar(255) NOT NULL default '',
`Rolename` varchar(255) NOT NULL default '',
`ApplicationName` varchar(255) NOT NULL default '',
PRIMARY KEY (`Username`,`Rolename`,`ApplicationName`)
);
There is an SQL file named DBStructure.sql included with the source code ZIP file that contains the code above.
-
Open Visual Studio and create a new Website Project.
-
Add a reference to the Simple.Providers.MySQL.dll file.
-
Make the following changes to your web.config file:
-
Add the connection string to your newly created database to the connectionStrings section, e.g. <add connectionstring="Driver={MySQL ODBC 3.51 Driver};server={Your Server IP};port={Your Server Port No.};option=3;database={New Database Name};uid={Your username};pwd={Your password}" name="SimpleProviderConnectionString" providername="System.Data.Odbc" />.
* Please replace the {Your Server IP}, {Your Server Port No.}, {New Database Name}, {Your username} and {Your password} entries in the connection string with your own values.
-
Under the <system.web> section add the following:
<siteMap defaultProvider="siteMapProvider" enabled="true">
<providers>
<clear />
<add name="siteMapProvider"
type="Simple.Providers.MySQL.MysqlSiteMapProvider"
connectionStringName="SimpleProviderConnectionString"
applicationName="{Your App Name}"
description="MySQL site map provider"
securityTrimmingEnabled="true"/>
</providers>
</siteMap>
<roleManager defaultProvider="roleProvider" enabled="true"
cacheRolesInCookie="false" cookieName=".ASPROLES"
cookieTimeout="7200" cookiePath="/" cookieRequireSSL="false"
cookieSlidingExpiration="true" cookieProtection="All">
<providers>
<clear />
<add name="roleProvider"
type="Simple.Providers.MySQL.MysqlRoleProvider"
connectionStringName="SimpleProviderConnectionString"
applicationName="{Your App Name}"
description="MySQL role provider"/>
</providers>
</roleManager>
<membership defaultProvider="membershipProvider"
userIsOnlineTimeWindow="15">
<providers>
<clear />
<add name="membershipProvider"
type="Simple.Providers.MySQL.MysqlMembershipProvider"
connectionStringName="SimpleProviderConnectionString"
applicationName="{Your App Name}"
enablePasswordRetrieval="true"
enablePasswordReset="true"
requiresQuestionAndAnswer="true"
requiresUniqueEmail="true" passwordFormat="Encrypted"
minRequiredPasswordLength="6"
minRequiredNonalphanumericCharacters="0"
description="MySQL membership provider"/>
</providers>
</membership>
<profile defaultProvider="profileProvider"
automaticSaveEnabled="true">
<providers>
<clear />
<add name="profileProvider"
type="Simple.Providers.MySQL.MysqlProfileProvider"
connectionStringName="SimpleProviderConnectionString"
applicationName="{Your App Name}"
description="MySQL Profile Provider"/>
</providers>
<properties>
<clear />
-->
</properties>
</profile>
<webParts>
<personalization defaultProvider="personalizationProvider">
<providers>
<clear />
<add name="personalizationProvider"
type="Simple.Providers.MySQL.
MysqlPersonalizationProvider"
connectionStringName=
"{Your Connection String Name}" applicationName="
{Your App Name}"
description="MySQL Personalization Provider/>
</providers>
</personalization>
</webParts>
/* !!! Please replace the {Your App Name} instances with a valid
application name. The application name should not contain
any spaces or special characters. !!! */
-
Everything should be set up correctly now. Continue with the rest of your project and make sure to make use of the features provided by the above mentioned providers.
[^]
I made use of the Microsoft MSDN site while developing the provider suite. For more info on...
[^]
- 2007-04-25: Initial release of the article
- 2007-10-18: Update of the
UpdateUser code to enable LastActivityDate functionality
[^]
| You must Sign In to use this message board. |
|
| | Msgs 1 to 25 of 109 (Total in Forum: 109) (Refresh) | FirstPrevNext |
|
 |
|
|
I get the same error as 'fpajaro' stated in an earlier message. Using passwordFormat = "Clear" works just fine This error occurs befóre an actual connection is made to the database, so the error lies not in there. Targeting framework 2.0, 3.0 or 3.5 makes no difference. It has to be in the membership provider implementation. Any help or suggestions on this are very welcome.
Otherwise nice coding and thanks for sharing it... ...
Michael Bakker, the Netherlands.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Hi Michael.
Encrypted or Hashed passwords has not been implemented in the providers.
"I'm about as expert as a palsy victim performing brain surgery with a pipe wrench." Check out my site at JacquesSnyman.co.za** Remember: An article is only as good as the votes it gets **
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Unlike a WebApplication Project Implementation in my ASP.NET WEB SITE qdo set in the web.config the name of my application that does not appear on the code of ASP.NET master page qdo WEBSITE he does not show the result of MySqlSiteMap or data in any control Navigation
applicationName="{Your App Name}"
My Web.Config
<siteMap defaultProvider="siteMapProvider" enabled="true">
<providers> <clear /> <add name="siteMapProvider" type="Simple.Providers.MySQL.MysqlSiteMapProvider" connectionStringName="SimpleProviderConnectionString" applicationName="AulasOnlineNet" description="MySQL site map provider" securityTrimmingEnabled="false"/> </providers>
</siteMap>
My Code Behind - Master.Page
using System; using System.Data; using System.Configuration; using System.Collections; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls;
public partial class Home : System.Web.UI.MasterPage {
protected void Page_Load(object sender, EventArgs e) {
} }
LADEF
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Dude!
I don't want to be nasty or anything, but I do not know what you want. You english is uncomprehendable.
Please learn english or get a good translator to translate for you.
"I'm about as expert as a palsy victim performing brain surgery with a pipe wrench." Check out my site at JacquesSnyman.co.za** Remember: An article is only as good as the votes it gets **
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Thanks anyway, but now thought to reply.Don't remember to add a reference to MySqlSiteMapProvider in my application Asp.Net Web Site is now working thanks
Translated from Portuguese to English by Google
LADEF
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
J. Snyman you could you explain why when I use a control-type sitemappath in currentnode, I explain what's happening
well let me explain you better then
My SiteMapProvider comes from below as MySqlSiteMapProvider <!-- INÖCIO CONFIGS MYSQLSITEMAPPROVIDER --> <siteMap defaultProvider="siteMapProvider" enabled="true">
<providers> <clear />
<add name="siteMapProvider"
type="Simple.Providers.MySQL.MysqlSiteMapProvider"
connectionStringName="SimpleProviderConnectionString"
applicationName="myapp"
description="MySQL site map provider"
securityTrimmingEnabled="true"/> </providers>
</siteMap>
<!-- FIM CONFIGS MYSQL SITEMAPPROVIDER -->
When the url it in my database in the field url MySqlSiteMapProvider is like this id, myapp, 'Atibaia-SP.', 'shops - Atibaia-SP.', 'shops.aspx?subsessao=books&cidade=atibaia&uf=sp', '', parentid it shows SiteMapPath in control of my application correctly or Home :shops : books : Atibaia-SP. Now when the data comes from my database of mysqlsitemapprovider that way id, myapp, 'São Paulo-SP.', 'shops - São Paulo-SP.', 'shops.aspx?subsessao=books&cidade=são paulo&uf=sp', '', parentid or id, myapp, 'Jundiaí-SP.', 'shops - Jundia-SP.', 'shops.aspx?subsessao=books&cidade=´jundiaí&uf=sp', '', parentid it just shows me this result in the control mode of execution in SiteMapPath Home : shops if you can help me now because I need to thank the currentnode, finally on all nodes that the accented characters with spaces and mapped by MySqlSiteMapProvider appear with accents and spaces in control sitemappath
LADEF
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
I'm sorry, but I can't understand what you are saying. Please get a decent translator to translate what you are trying to sy to english.
"I'm about as expert as a palsy victim performing brain surgery with a pipe wrench." Check out my site at JacquesSnyman.co.za** Remember: An article is only as good as the votes it gets **
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Hello J Snyman as can be seen in the web.config of my asp.net 2.0 application that I am doing in VisualStudio2005 I have a 2 providers SqlSiteMapProvider which is the standard for use with authentication and security based on MemberShipProvider and another to use only the MySqlSiteMapProvider who also uses Roles of the MemberShipProvider the standard SQLServer as can be seen below in web.config
<appSettings/>
<connectionStrings>
<add name="MembershipConnection" connectionString="Data Source=mydatasource;Initial Catalog=mydb;User ID=sa;Password=mypass" providerName="System.Data.SqlClient"/>
<add connectionString="server=mysqlserver;database=mybd;user id=myid;pwd=mypass" name="SimpleProviderConnectionString" providerName="MySql.Data.MySqlClient"/>
</connectionStrings>
<system.web>
<membership defaultProvider="SqlProvider" userIsOnlineTimeWindow="15">
<providers>
<clear/>
<add name="SqlProvider" type="System.Web.Security.SqlMemberShipProvider"
connectionStringName="MembershipConnection"/>
</providers>
</membership>
<!-- INÍCIO CONFIGS MYSQLSITEMAPPROVIDER -->
<siteMap defaultProvider="siteMapProvider" enabled="true">
<providers>
<clear />
<add name="siteMapProvider"
type="Simple.Providers.MySQL.MysqlSiteMapProvider"
connectionStringName="SimpleProviderConnectionString"
applicationName="myapp"
description="MySQL site map provider"
securityTrimmingEnabled="true"/>
</providers>
</siteMap>
<authentication mode="Forms">
</authentication>
What you need to know is how to properly configure so that the two providers one for each state are recognized and work properly in my webapplication Project and how to ensure that the roles created Membership in the SQL are recognized in MySqlSiteMapProvider too.
If you can help me now thank you
Translated from Portuguese to English by Google
LADEF
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
I have been using the Membership provider for some time. Now I have added som 400 users, and I find (confirmed on 3 different servers) that it takes 10 seconds or more from the time you press the "Login"-button until you are actually logged in. Same thing when you press "log out".
Has anyone got any ideas on how to improve speeed? Code-optimazation, database-optimization...
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
I would start by looking at the SQL queries that are used when a user logs in/out.
Another solution might be to migrate to the MySQL/Net Connector that has Membership providers built in.
"I'm about as expert as a palsy victim performing brain surgery with a pipe wrench."
** Remember: An article is only as good as the votes it gets **
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Do you have any experience with MySQL/Net Connector? Last time I looked, it was in som beta-test-stadium?
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Unfortunately not.
I have read on the MySql site that the connector is now in productions release and stable.
"I'm about as expert as a palsy victim performing brain surgery with a pipe wrench." Check out my site at JacquesSnyman.co.za** Remember: An article is only as good as the votes it gets **
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
OK thx. Meanwhile I fond a bug of my own, having nothing to do with your connector. So I'll stick with that for now.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
When I set passwordFormat="Encrypted" under the membership tag of my web.config file, I am receiving the following error when I click on the security link of the ASP.NET Configuration tool:
Hashed or Encrypted passwords are not supported with auto-generated keys
The same happens when I set passwordFormat="Hashed"
Any help on this would be highly appreciated!
|
| Sign In·View Thread·PermaLink | 2.00/5 (7 votes) |
|
|
|
 |
|
|
Dear Jacques, many thanks for your excellent post. I am a real newbie to asp, having spent 25 years in 4GLs, and I have spent the last 3 days trying to find out how to use MySQL database as a membership database, so I can use the CreateUserWizard in my aspx files. I have finally, with your help, get as far as the whole application running without errors in the web.config file, however now when I go to the createuserwizard page, I get the error below. I can't for the life of me work out where this is going wrong. I have reduced it to just the rolemanager and membership bit in the web.config, and have changed the cookiepath to ~/cookies. I have added <@ Import Namespace="Simple.Providers.MySQL" %> into my master page, and your dll into the bin directory of my application.
Where am I going wrong???? Any help would be greatly appreciated to stop me going completely bananas on this (should be simple) issue!
Kind Regards, Ross Holland
Stack Trace:
[InvalidOperationException: Failed to map the path '/'.] System.Web.Configuration.ProcessHostConfigUtils.MapPathActual(String siteName, VirtualPath path) +223 System.Web.Configuration.ProcessHostMapPath.MapPathCaching(String siteID, VirtualPath path) +611 System.Web.Configuration.ProcessHostMapPath.GetPathConfigFilenameWorker(String siteID, VirtualPath path, String& directory, String& baseName) +14 System.Web.Configuration.ProcessHostMapPath.System.Web.Configuration.IConfigMapPath.GetPathConfigFilename(String siteID, String path, String& directory, String& baseName) +38 System.Web.Configuration.HostingPreferredMapPath.GetPathConfigFilename(String siteID, String path, String& directory, String& baseName) +77 System.Web.Configuration.WebConfigurationHost.GetStreamName(String configPath) +162 System.Configuration.Internal.DelegatingConfigHost.GetStreamName(String configPath) +10 System.Configuration.BaseConfigurationRecord.InitConfigFromFile() +265
[ConfigurationErrorsException: An error occurred loading a configuration file: Failed to map the path '/'.] System.Configuration.ConfigurationSchemaErrors.ThrowIfErrors(Boolean ignoreLocal) +111 System.Configuration.BaseConfigurationRecord.ThrowIfParseErrors(ConfigurationSchemaErrors schemaErrors) +41 System.Configuration.Configuration..ctor(String locationSubPath, Type typeConfigHost, Object[] hostInitConfigurationParams) +413 System.Configuration.Internal.InternalConfigConfigurationFactory.System.Configuration.Internal.IInternalConfigConfigurationFactory.Create(Type typeConfigHost, Object[] hostInitConfigurationParams) +30 System.Web.Configuration.WebConfigurationHost.OpenConfiguration(WebLevel webLevel, ConfigurationFileMap fileMap, VirtualPath path, String site, String locationSubPath, String server, String userName, String password, IntPtr tokenHandle) +934 System.Web.Configuration.WebConfigurationManager.OpenWebConfigurationImpl(WebLevel webLevel, ConfigurationFileMap fileMap, String path, String site, String locationSubPath, String server, String userName, String password, IntPtr userToken) +71 System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration(String path) +23 Simple.Providers.MySQL.MysqlMembershipProvider.Initialize(String name, NameValueCollection config) +1429 System.Web.Configuration.ProvidersHelper.InstantiateProvider(ProviderSettings providerSettings, Type providerType) +579 System.Web.Configuration.ProvidersHelper.InstantiateProviders(ProviderSettingsCollection configProviders, ProviderCollection providers, Type providerType) +115 System.Web.Security.Membership.Initialize() +1593 System.Web.UI.WebControls.LoginUtil.GetProvider(String providerName) +33 System.Web.UI.WebControls.CreateUserWizard.get_QuestionAndAnswerRequired() +90 System.Web.UI.WebControls.CreateUserWizard.UpdateValidators() +1134 System.Web.UI.WebControls.CreateUserWizard.CreateChildControls() +32 System.Web.UI.Control.EnsureChildControls() +97 System.Web.UI.WebControls.Wizard.OnInit(EventArgs e) +100 System.Web.UI.Control.InitRecursive(Control namingContainer) +345 System.Web.UI.Control.InitRecursive(Control namingContainer) +196 System.Web.UI.Control.InitRecursive(Control namingContainer) +196 System.Web.UI.Control.InitRecursive(Control namingContainer) +196 System.Web.UI.Control.InitRecursive(Control namingContainer) +196 System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +7915 System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +223 System.Web.UI.Page.ProcessRequest() +85 System.Web.UI.Page.ProcessRequestWithNoAssert(HttpContext context) +20 System.Web.UI.Page.ProcessRequest(HttpContext context) +110 ASP.register_aspx.ProcessRequest(HttpContext context) +30 System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +441 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +65
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Hi Ross...
Could you please post your web.config file? I would like to get the complete picture before trying to decipher the error.
Regards Jacques Snyman
"I'm about as expert as a palsy victim performing brain surgery with a pipe wrench." Check out my site at JacquesSnyman.co.za** Remember: An article is only as good as the votes it gets **
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Dear Jacques, hope this helps, Cheers Ross
<configuration> <connectionStrings> <add name="MyDB" connectionString="driver={MySQL ODBC 3.51 Driver};database=userid;option=16387;pwd=password;port=0;server=server-ip;uid=userid" providerName="System.Data.Odbc" /> </connectionStrings> <system.web> <customErrors mode="Off" /> <compilation debug="true" /> <authentication mode="Forms"> <forms loginUrl="login.aspx" /> </authentication> <roleManager defaultProvider="roleProvider" enabled="true" cacheRolesInCookie="false" cookieName=".ASPROLES" cookieTimeout="7200" cookiePath="~/cookies" cookieRequireSSL="false" cookieSlidingExpiration="true" cookieProtection="All"> <providers> <clear /> <add name="roleProvider" type="Simple.Providers.MySQL.MysqlRoleProvider" connectionStringName="MyDB" applicationName="myapp.org.uk" description="MySQL role provider"/> </providers> </roleManager> <membership defaultProvider="membershipProvider" userIsOnlineTimeWindow="15"> <providers> <clear /> <add name="membershipProvider" type="Simple.Providers.MySQL.MysqlMembershipProvider" connectionStringName="MyDB" applicationName="myapp.org.uk" enablePasswordRetrieval="true" enablePasswordReset="true" requiresQuestionAndAnswer="true" requiresUniqueEmail="true" passwordFormat="Encrypted" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" description="MySQL membership provider"/> </providers> </membership> </system.web> <location path="MembersOnly"> <system.web> <authorization> <deny users="?" /> </authorization> </system.web> </location> </configuration>
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
The only issue I can see is that the tilde (~) might not be parsed by the server because it is in the config file. Have you tried to use a relative path (eg "/cookies/")?
Does the cookies directory exist?
"I'm about as expert as a palsy victim performing brain surgery with a pipe wrench." Check out my site at JacquesSnyman.co.za** Remember: An article is only as good as the votes it gets **
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Hello J Snyman, Compliments for the article is very interesting I use Visual Studio 2008 c#, mysql 5 and ADO.NET Driver for MySQL (Connector/NET) I am trying to work your suite, but I have difficulties.
In Web Site Administration Tool ------------------------------------------------------------------- An exception occurred communicating with the data source.
Action: GetAllUsers
Exception: System.Data.Odbc.OdbcException: ERROR [IM002] [Microsoft][Driver Manager ODBC] Nome origine dati non trovato e driver predefinito non specificato. at System.Data.Odbc.OdbcConnection.HandleError(OdbcHandle hrHandle, RetCode retcode) at System.Data.Odbc.OdbcConnectionHandle..ctor(OdbcConnection connection, OdbcConnectionString constr, OdbcEnvironmentHandle environmentHandle) at System.Data.Odbc.OdbcConnectionFactory.CreateConnection(DbConnectionOptions options, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningObject) at System.Data.ProviderBase.DbConnectionFactory.CreateNonPooledConnection(DbConnection owningConnection, DbConnectionPoolGroup poolGroup) at System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection) at System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory) at System.Data.Odbc.OdbcConnection.Open() at Simple.Providers.MySQL.MysqlMembershipProvider.GetAllUsers(Int32 pageIndex, Int32 pageSize, Int32& totalRecords)
Per ulteriori informazioni, consultare la Guida in linea e supporto tecnico -------------------------------------------------------------------
In login.aspx ------------------------------------------------------------- | | | | | |