Link to home
Start Free TrialLog in
Avatar of dbrckovi
dbrckoviFlag for Croatia

asked on

Using SqlMembershipProvider in desktop application

Hi!

I'm creating a desktop application which will be used to automate some administrative tasks on a database which is mainly used as  database behind a web page.

Web application is using aspnet user and role management, so all users, roles, passwords etc. are stored in our database in auto generated tables with prefix 'aspnet_'.

Now I have to create a way to authenticate aspnet users in my desktop application.
How can I do that?

I tried using System.Web.Security.SqlMembershipProvider.ValidateUser ("username","password"), but it throws 'Object reference not set to an instance of an object'.

I tried copying <providers> tag in many different ways from web application's web.config to my app.config but no matter what I do, I'm getting the same error.

As you probably might have figured, I have never used aspnet authentication in desktop or web application, so I have no idea how this works, or if it is even possible to make it work in the way I want.

If there's no way to make SqlMembershipProvider work in desktop application, is there a way to encrypt and compare user's password to a stored password in aspnet_Membership.Password field?

Basically all I need to do is find out if user's password is correct and get his userID.
Avatar of Bob Learned
Bob Learned
Flag of United States of America image

I have never used the SqlMembershipProvider in a Windows Forms application, so this is going to require some investigation.  I usually start with the full stack trace of the exception.  That will help to narrow the cause for the 'Object reference not set" exception.
Avatar of dbrckovi

ASKER

It doesn't have inner exception. It's null.
This is my code:
            try
            {
                System.Web.Security.SqlMembershipProvider provider = new System.Web.Security.SqlMembershipProvider();
                provider.ValidateUser("test", "test");
            }
            catch (Exception ex)
            {
                if (ex.InnerException != null)
                {
                    MessageBox.Show(ex.InnerException.Message);
                }
                MessageBox.Show(ex.Message);
            }

Open in new window

What exactly does my app.config need for this to work? I guess it needs at least a connection string to my database. But I tried copying all kinds of tags from web.config containing database and security data, but nothing changed. The message is allways the same.
What does ex.ToString equal?
System.NullReferenceException: Object reference not set to an instance of an object.
   at System.Web.DataAccess.SqlConnectionHelper.GetConnection(String connectionString, Boolean revertImpersonation)
   at System.Web.Security.SqlMembershipProvider.GetPasswordWithFormat(String username, Boolean updateLastLoginActivityDate, Int32& status, String& password, Int32& passwordFormat, String& passwordSalt, Int32& failedPasswordAttemptCount, Int32& failedPasswordAnswerAttemptCount, Boolean& isApproved, DateTime& lastLoginDate, DateTime& lastActivityDate)
   at System.Web.Security.SqlMembershipProvider.CheckPassword(String username, String password, Boolean updateLastLoginActivityDate, Boolean failIfNotApproved, String& salt, Int32& passwordFormat)
   at System.Web.Security.SqlMembershipProvider.CheckPassword(String username, String password, Boolean updateLastLoginActivityDate, Boolean failIfNotApproved)
   at System.Web.Security.SqlMembershipProvider.ValidateUser(String username, String password)
   at SeatAdmin.Forms.frmSeatAdmin.button1_Click(Object sender, EventArgs e) in C:\GIT\Svjetsko prvenstvo\SVN\Source\Desktop\SeatAdmin\SeatAdmin\Forms\frmSeatAdmin.cs:line 57
If it can help, this is the contents of web.config.template we use in our web application. I have only changed some sensitive data to 'hidden'.
<?xml version="1.0"?>
<!-- 
    Note: As an alternative to hand editing this file you can use the 
    web admin tool to configure settings for your application. Use
    the Website->Asp.Net Configuration option in Visual Studio.
    A full list of settings and comments can be found in 
    machine.config.comments usually located in 
    \Windows\Microsoft.Net\Framework\v2.x\Config 
-->
<configuration>
  <configSections>
    <sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
      <sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
        <section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
        <sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
          <section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="Everywhere"/>
          <section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
          <section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
          <section name="roleService" type="System.Web.Configuration.ScriptingRoleServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
        </sectionGroup>
      </sectionGroup>
    </sectionGroup>
  </configSections>
  <appSettings>
    <add key="Currency" value="kn"/>
    <add key="ProjectID" value="1"/>
    <add key="ShopID" value="10000371"/>
    <add key="SecretKey" value="hidden"/>
    <add key="appTheme" value="xp_silver"/>
    <add key="TempFolder" value="E:\kum\hidden"/>
    <add key="TempVirtualDir" value="/hidden/Temp/"/>
    <add key="ProjectUID" value="1"/>
    <!-- Business object connection string -->
    <add key="dbConnection" value="Data Source=hidden\SQLEXPRESS;Initial Catalog=hidden;Integrated Security=True"/>
  </appSettings>
  <connectionStrings>
    <add name="DefaultConnection" providerName="System.Data.SqlClient" connectionString="Data Source=hidden\SQLEXPRESS;Initial Catalog=hidden;Integrated Security=True"/>
    <add name="hiddenConnectionString" providerName="System.Data.SqlClient" connectionString="Data Source=hidden\SQLEXPRESS;Initial Catalog=hidden;Integrated Security=True"/>
  </connectionStrings>
  <system.web>
    <healthMonitoring enabled="true">
      <eventMappings>
        <clear/>
        <!--all unhandled exceptions or explicitly raised error events-->
        <add name="All Events" type="System.Web.Management.WebBaseEvent" startEventCode="0" endEventCode="2147483647"/>
        <add name="All Errors" type="System.Web.Management.WebBaseErrorEvent" startEventCode="0" endEventCode="2147483647"/>
        <add name="Failure Audits" type="System.Web.Management.WebFailureAuditEvent" startEventCode="0" endEventCode="2147483647"/>
        <add name="Auth Failure Audits" type="System.Web.Management.WebAuthenticationFailureAuditEvent" startEventCode="0" endEventCode="2147483647" />
        <add name="Auth Success Audits" type="System.Web.Management.WebAuthenticationSuccessAuditEvent" startEventCode="0" endEventCode="2147483647" />
        <add name="Custom Audits" type="MyWebEvents.WebCustomAuditEvent" startEventCode="0" endEventCode="2147483647" />
 
      </eventMappings>
 
      <providers>
        <clear/>
        <!--Windows Application Event Log-->
        <add name="EventLogProvider" type="System.Web.Management.EventLogWebEventProvider"/>
        <!--SQL Server Event Log-->
        <add name="SqlWebEventProvider" type="System.Web.Management.SqlWebEventProvider" connectionStringName="DefaultConnection" maxEventDetailsLength="1073741823" buffer="false" bufferMode="Notification"/>
        <!--WMI Event Log-->
        <add name="WmiWebEventProvider" type="System.Web.Management.WmiWebEventProvider"/>
      </providers>
 
      <rules>
        <clear/>
        <!--<add name="All Errors Default" eventName="All Errors" provider="EventLogProvider" profile="Default" minInstances="1" maxLimit="Infinite" minInterval="00:00:00" custom=""/>-->
        <!--<add name="All Events Default" eventName="All Events" provider="EventLogProvider" profile="Default" minInstances="1" maxLimit="Infinite" minInterval="00:00:00" custom=""/>-->
        <add name="All Errors Default" eventName="All Errors" provider="EventLogProvider" profile="Default" minInstances="1" maxLimit="Infinite" minInterval="00:00:00" custom=""/>
        <add name="All Errors SQL" eventName="All Errors" provider="SqlWebEventProvider" profile="Default" minInstances="1" maxLimit="Infinite" minInterval="00:00:00" custom=""/>
        <add name="Failure Audits Default" eventName="Failure Audits" provider="EventLogProvider" profile="Default" minInstances="1" maxLimit="Infinite" minInterval="00:00:00" custom=""/>
        <add name="Auth Failure Audits Default" eventName="Auth Failure Audits" provider="EventLogProvider" profile="Default" minInstances="1" maxLimit="Infinite" minInterval="00:00:00" custom=""/>
        <add name="Auth Success Audits Default" eventName="Auth Success Audits" provider="EventLogProvider" profile="Default" minInstances="1" maxLimit="Infinite" minInterval="00:00:00" custom=""/>
        <add name="Auth Failure Audits SQL" eventName="Auth Failure Audits" provider="SqlWebEventProvider" profile="Default" minInstances="1" maxLimit="Infinite" minInterval="00:00:00" custom=""/>
        <add name="Auth Success Audits SQL" eventName="Auth Success Audits" provider="SqlWebEventProvider" profile="Default" minInstances="1" maxLimit="Infinite" minInterval="00:00:00" custom=""/>
        <add name="Custom Audits Default" eventName="Custom Audits" provider="EventLogProvider" profile="Default" minInstances="1" maxLimit="Infinite" minInterval="00:00:00" custom=""/>
        <add name="Custom Audits SQL" eventName="Custom Audits" provider="SqlWebEventProvider" profile="Default" minInstances="1" maxLimit="Infinite" minInterval="00:00:00" custom=""/>
 
      </rules>
    </healthMonitoring>
    <!--
          Set compilation debug="true" to insert debugging
          symbols into the compiled page. Because this
          affects performance, set this value to true only
          during development.
        -->
    <!--
       The mode attribute of customErrors can be one of the following:
       On  error details are not shown to anybody, even local users. 
            If you specified a custom error page it will be always used. 
       Off  everyone will see error details, both local and remote users. 
             If you specified a custom error page it will NOT be used. 
       RemoteOnly  local users will see detailed error pages with a stack 
                    trace and compilation details, while remote users with 
                    be presented with a concise page notifying them that an error occurred. 
                    If a custom error page is available, it will be shown to the remote users only. 
    -->
    <customErrors mode="RemoteOnly" defaultRedirect="~/public/CustomErrorPage.aspx" />
    <sessionState timeout="30" />
    <compilation debug="true" defaultLanguage="c#">
      <assemblies>
        <add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
        <add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
        <add assembly="System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
        <add assembly="System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
        <add assembly="System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
        <add assembly="Microsoft.ReportViewer.WebForms, Version=9.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>
        <add assembly="Microsoft.ReportViewer.Common, Version=9.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>
      </assemblies>
    </compilation>
    <authorization>
      <!--<allow users="*"/>-->
      <deny users="?"/>
    </authorization>
    <!--
            The <authentication> section enables configuration 
            of the security authentication mode used by 
            ASP.NET to identify an incoming user. 
        -->
    <authentication mode="Forms">
      <forms loginUrl="Login.aspx" defaultUrl="~/Default.aspx" timeout="43200" />
    </authentication>
    <roleManager enabled="true" defaultProvider="MySqlRoleProvider">
      <providers>
        <add connectionStringName="DefaultConnection"
             applicationName="/"
             name="MySqlRoleProvider"
             type="System.Web.Security.SqlRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
      </providers>
    </roleManager>
    <membership defaultProvider="MySqlMembershipProvider">
      <providers>
        <clear/>
        <add connectionStringName="DefaultConnection"
             name="MySqlMembershipProvider"
             type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
             enablePasswordRetrieval="false"
             enablePasswordReset="true"
             requiresQuestionAndAnswer="true"
             applicationName="/"
             requiresUniqueEmail="false"
             passwordFormat="Hashed"
             maxInvalidPasswordAttempts="3"
             minRequiredPasswordLength="6"
             minRequiredNonalphanumericCharacters="0"
             passwordAttemptWindow="10" />
      </providers>
    </membership>
    <siteMap defaultProvider="XmlSiteMapProvider" enabled="true">
      <providers>
        <add name="XmlSiteMapProvider"
             description="Default SiteMap provider."
             type="System.Web.XmlSiteMapProvider"
             siteMapFile="Web.sitemap"
             securityTrimmingEnabled="true" />
      </providers>
    </siteMap>
    <profile defaultProvider="MySqlProfileProvider">
      <providers>
        <add connectionStringName="DefaultConnection"
             name="MySqlProfileProvider"
             applicationName="/"
             type="System.Web.Profile.SqlProfileProvider"/>
      </providers>
      <properties>
        <add name="PersonID" type="System.Int32"/>
        <add name="PartnerID" type="System.Int32"/>
        <add name="ProjectUID" type="System.Int32"/>
        <add name="PCentarID" type="System.Int32"/>
      </properties>
    </profile>
    <!--<globalization culture="hr-HR" uiCulture="hr-HR"/>-->
    <globalization culture="en-GB" uiCulture="en-GB"/>
    <!--
            The <customErrors> section enables configuration 
            of what to do if/when an unhandled error occurs 
            during the execution of a request. Specifically, 
            it enables developers to configure html error pages 
            to be displayed in place of a error stack trace.
 
        <customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">
            <error statusCode="403" redirect="NoAccess.htm" />
            <error statusCode="404" redirect="FileNotFound.htm" />
        </customErrors>
        -->
    <pages>
      <controls>
        <add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
        <add tagPrefix="asp" namespace="System.Web.UI.WebControls" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
      </controls>
    </pages>
    <httpHandlers>
      <remove verb="*" path="*.asmx"/>
      <add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
      <add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
      <add path="Reserved.ReportViewerWebControl.axd" verb="*" type="Microsoft.Reporting.WebForms.HttpHandler, Microsoft.ReportViewer.WebForms, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" validate="false"/>
      <add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" validate="false"/>
    </httpHandlers>
    <httpModules>
      <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
    </httpModules>
  </system.web>
  <system.web.extensions>
    <scripting>
      <webServices>
        <!-- Uncomment this line to customize maxJsonLength and add a custom converter -->
        <!--
      <jsonSerialization maxJsonLength="500">
        <converters>
          <add name="ConvertMe" type="Acme.SubAcme.ConvertMeTypeConverter"/>
        </converters>
      </jsonSerialization>
      -->
        <!-- Uncomment this line to enable the authentication service. Include requireSSL="true" if appropriate. -->
        <!--
        <authenticationService enabled="true" requireSSL = "true|false"/>
      -->
        <!-- Uncomment these lines to enable the profile service. To allow profile properties to be retrieved
           and modified in ASP.NET AJAX applications, you need to add each property name to the readAccessProperties and
           writeAccessProperties attributes. -->
        <!--
      <profileService enabled="true"
                      readAccessProperties="propertyname1,propertyname2"
                      writeAccessProperties="propertyname1,propertyname2" />
      -->
      </webServices>
      <!--
      <scriptResourceHandler enableCompression="true" enableCaching="true" />
      -->
    </scripting>
  </system.web.extensions>
  <system.codedom>
    <compilers>
      <compiler language="c#;cs;csharp" extension=".cs" warningLevel="4" type="Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
        <providerOption name="CompilerVersion" value="v3.5"/>
        <providerOption name="WarnAsError" value="false"/>
      </compiler>
      <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" warningLevel="4" type="Microsoft.VisualBasic.VBCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
        <providerOption name="CompilerVersion" value="v3.5"/>
        <providerOption name="OptionInfer" value="true"/>
        <providerOption name="WarnAsError" value="false"/>
      </compiler>
    </compilers>
  </system.codedom>
  <!-- 
        The system.webServer section is required for running ASP.NET AJAX under Internet
        Information Services 7.0.  It is not necessary for previous version of IIS.
    -->
  <system.webServer>
    <validation validateIntegratedModeConfiguration="false"/>
    <modules>
      <remove name="ScriptModule"/>
      <add name="ScriptModule" preCondition="managedHandler" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
    </modules>
    <handlers>
      <remove name="WebServiceHandlerFactory-Integrated"/>
      <remove name="ScriptHandlerFactory"/>
      <remove name="ScriptHandlerFactoryAppServices"/>
      <remove name="ScriptResource"/>
      <add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
      <add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
      <add name="ScriptResource" preCondition="integratedMode" verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
    </handlers>
  </system.webServer>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Extensions" publicKeyToken="31bf3856ad364e35"/>
        <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0"/>
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Extensions.Design" publicKeyToken="31bf3856ad364e35"/>
        <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0"/>
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
  <system.net>
    <mailSettings>
      <smtp from="hidden@hidden.com">
        <network host="mail.hidden.hr" port="25" />
      </smtp>
    </mailSettings>
  </system.net>
</configuration>

Open in new window

This is the SqlMembershipProvider's GetPasswordWithFormat method:


private void GetPasswordWithFormat(string username, bool updateLastLoginActivityDate, out int status, out string password, out int passwordFormat, out string passwordSalt, out int failedPasswordAttemptCount, out int failedPasswordAnswerAttemptCount, out bool isApproved, out DateTime lastLoginDate, out DateTime lastActivityDate)
{
    try
    {
        SqlConnectionHolder connection = null;
        SqlDataReader reader = null;
        SqlParameter parameter = null;
        try
        {
            connection = SqlConnectionHelper.GetConnection(this._sqlConnectionString, true);
            this.CheckSchemaVersion(connection.Connection);
            SqlCommand command = new SqlCommand("dbo.aspnet_Membership_GetPasswordWithFormat", connection.Connection) {
                CommandTimeout = this.CommandTimeout,
                CommandType = CommandType.StoredProcedure
            };
            command.Parameters.Add(this.CreateInputParam("@ApplicationName", SqlDbType.NVarChar, this.ApplicationName));
            command.Parameters.Add(this.CreateInputParam("@UserName", SqlDbType.NVarChar, username));
            command.Parameters.Add(this.CreateInputParam("@UpdateLastLoginActivityDate", SqlDbType.Bit, updateLastLoginActivityDate));
            command.Parameters.Add(this.CreateInputParam("@CurrentTimeUtc", SqlDbType.DateTime, DateTime.UtcNow));
            parameter = new SqlParameter("@ReturnValue", SqlDbType.Int) {
                Direction = ParameterDirection.ReturnValue
            };
            command.Parameters.Add(parameter);
            reader = command.ExecuteReader(CommandBehavior.SingleRow);
            status = -1;
            if (reader.Read())
            {
                password = reader.GetString(0);
                passwordFormat = reader.GetInt32(1);
                passwordSalt = reader.GetString(2);
                failedPasswordAttemptCount = reader.GetInt32(3);
                failedPasswordAnswerAttemptCount = reader.GetInt32(4);
                isApproved = reader.GetBoolean(5);
                lastLoginDate = reader.GetDateTime(6);
                lastActivityDate = reader.GetDateTime(7);
            }
            else
            {
                password = null;
                passwordFormat = 0;
                passwordSalt = null;
                failedPasswordAttemptCount = 0;
                failedPasswordAnswerAttemptCount = 0;
                isApproved = false;
                lastLoginDate = DateTime.UtcNow;
                lastActivityDate = DateTime.UtcNow;
            }
        }
        finally
        {
            if (reader != null)
            {
                reader.Close();
                reader = null;
                status = (parameter.Value != null) ? ((int) parameter.Value) : -1;
            }
            if (connection != null)
            {
                connection.Close();
                connection = null;
            }
        }
    }
    catch
    {
        throw;
    }
}

Open in new window

This is where the _sqlConnectionString field is set:

<summary>Initializes the SQL Server membership provider with the property values specified in the ASP.NET application's configuration file. This method is not intended to be used directly from your code.</summary>

        /// <summary>Initializes the SQL Server membership provider with the property values specified in the ASP.NET application's configuration file. This method is not intended to be used directly from your code.</summary>
        /// <param name="config">A <see cref="T:System.Collections.Specialized.NameValueCollection"></see> that contains the names and values of configuration options for the membership provider. </param>
        /// <param name="name">The name of the <see cref="T:System.Web.Security.SqlMembershipProvider"></see> instance to initialize. </param>
        /// <exception cref="T:System.Web.HttpException">The current trust level is less than Low.</exception>
        /// <exception cref="T:System.ArgumentNullException">config is null.</exception>
        /// <exception cref="T:System.InvalidOperationException">The provider has already been initialized prior to the current call to the <see cref="M:System.Web.Security.SqlMembershipProvider.Initialize(System.String,System.Collections.Specialized.NameValueCollection)"></see> method.</exception>
        /// <exception cref="T:System.Configuration.Provider.ProviderException">The enablePasswordRetrieval, enablePasswordReset, requiresQuestionAndAnswer, or requiresUniqueEmail attribute is set to a value other than a Boolean.- or -The maxInvalidPasswordAttempts or the passwordAttemptWindow attribute is set to a value other than a positive integer.- or -The minRequiredPasswordLength attribute is set to a value other than a positive integer, or the value is greater than 128.- or -The minRequiredNonalphanumericCharacters attribute is set to a value other than zero or a positive integer, or the value is greater than 128.- or -The value for the passwordStrengthRegularExpression attribute is not a valid regular expression.- or -The applicationName attribute is set to a value that is greater than 256 characters.- or -The passwordFormat attribute specified in the application configuration file is an invalid <see cref="T:System.Web.Security.MembershipPasswordFormat"></see> enumeration.- or -The passwordFormat attribute is set to <see cref="F:System.Web.Security.MembershipPasswordFormat.Hashed"></see> and the enablePasswordRetrieval attribute is set to true in the application configuration.- or -The passwordFormat attribute is set to Encrypted and the machineKey configuration element specifies AutoGenerate for the decryptionKey attribute.- or -The connectionStringName attribute is empty or does not exist in the application configuration.- or - The value of the connection string for the connectionStringName attribute value is empty, or the specified connectionStringName does not exist in the application configuration file.- or - The value for the commandTimeout attribute is set to a value other than zero or a positive integer.- or -The application configuration file for this <see cref="T:System.Web.Security.SqlMembershipProvider"></see> instance contains an unrecognized attribute.</exception>
        public override void Initialize(string name, NameValueCollection config)
 
...
 
            this._sqlConnectionString = SqlConnectionHelper.GetConnectionString(specifiedConnectionString, true, true);

Open in new window

Thank you!

GetPasswordWithFormat looks like exactly what I need. I will try it a bit later and post back the results.
I've modified the method a bit and now I can get password, passwordFormat, and passwordSalt.
Is the algorythm which stores the real password in the database public?
If it is, how do I do the same thing?
All I want is to encrypt the real password and hopefully if it's correct it should be equal to password returned by GetPasswordWithFormat.
I feel like the game today is "Stump the Expert".  I have no idea about that algorithm. :(
ASKER CERTIFIED SOLUTION
Avatar of Bob Learned
Bob Learned
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thank you!
It worked.

Here's th complete code I'm using:
//get existing password from database
        public static void ASPGetPasswordWithFormat(string username, bool updateLastLoginActivityDate, out int status, out string password, out int passwordFormat, out string passwordSalt, out int failedPasswordAttemptCount, out int failedPasswordAnswerAttemptCount, out bool isApproved, out DateTime lastLoginDate, out DateTime lastActivityDate)
        {
            try
            {
                SqlConnection conn = null;
                SqlDataReader reader = null;
                SqlParameter parameter = null;
                try
                {
                    conn = new SqlConnection(System.Configuration.ConfigurationSettings.AppSettings["dbConnection"].ToString());
                    SqlCommand command = new SqlCommand("dbo.aspnet_Membership_GetPasswordWithFormat", conn)
                    {
                        CommandType = CommandType.StoredProcedure
                    };
                    command.Parameters.Add("@ApplicationName", SqlDbType.NVarChar).Value = "/";
                    command.Parameters.Add("@UserName", SqlDbType.NVarChar).Value = username;
                    command.Parameters.Add("@UpdateLastLoginActivityDate", SqlDbType.Bit).Value = updateLastLoginActivityDate;
                    command.Parameters.Add("@CurrentTimeUtc", SqlDbType.DateTime).Value = DateTime.UtcNow;
                    parameter = new SqlParameter("@ReturnValue", SqlDbType.Int)
                    {
                        Direction = ParameterDirection.ReturnValue
                    };
                    command.Parameters.Add(parameter);
                    conn.Open();
                    reader = command.ExecuteReader(CommandBehavior.SingleRow);
                    status = -1;
                    if (reader.Read())
                    {
                        password = reader.GetString(0);
                        passwordFormat = reader.GetInt32(1);
                        passwordSalt = reader.GetString(2);
                        failedPasswordAttemptCount = reader.GetInt32(3);
                        failedPasswordAnswerAttemptCount = reader.GetInt32(4);
                        isApproved = reader.GetBoolean(5);
                        lastLoginDate = reader.GetDateTime(6);
                        lastActivityDate = reader.GetDateTime(7);
                    }
                    else
                    {
                        password = null;
                        passwordFormat = 0;
                        passwordSalt = null;
                        failedPasswordAttemptCount = 0;
                        failedPasswordAnswerAttemptCount = 0;
                        isApproved = false;
                        lastLoginDate = DateTime.UtcNow;
                        lastActivityDate = DateTime.UtcNow;
                    }
                }
                finally
                {
                    if (reader != null)
                    {
                        reader.Close();
                        reader = null;
                        status = (parameter.Value != null) ? ((int)parameter.Value) : -1;
                    }
                    if (conn != null)
                    {
                        conn.Close();
                        conn = null;
                    }
                }
            }
            catch
            {
                throw;
            }
        }
 
 
//used to encrypt typed password
    class MyMembership : SqlMembershipProvider
    {
        public new byte[] EncryptPassword(byte[] password)
        {
            return base.EncryptPassword(password);
        }
 
        public static string EncodePassword(string pass, byte passwordFormat, string salt)
        {
            //salt the password, then encrypt the salted password 
            if (passwordFormat == 0)
            {
                return pass;
            }
 
            byte[] bIN = Encoding.Unicode.GetBytes(pass);
            byte[] bSalt = Convert.FromBase64String(salt);
            byte[] bAll = new Byte[bSalt.Length + bIN.Length]; //this is the key to the code, shorten the salt, but only in VB, not C#
            byte[] bRet = null;
 
            System.Buffer.BlockCopy(bSalt, 0, bAll, 0, bSalt.Length);
            System.Buffer.BlockCopy(bIN, 0, bAll, bSalt.Length, bIN.Length);
 
            if (passwordFormat == 1)
            {
                System.Security.Cryptography.HashAlgorithm s = System.Security.Cryptography.HashAlgorithm.Create(System.Web.Security.Membership.HashAlgorithmType);
                bRet = s.ComputeHash(bAll);
            }
            else
            {
                SeatAdmin.Classes.MyMembership o = new SeatAdmin.Classes.MyMembership();
                bRet = o.EncryptPassword(bAll);
            }
 
            return Convert.ToBase64String(bRet);
        }    
    }
 
 
 
//usage
        private void button1_Click(object sender, EventArgs e)
        {
            int status = -1;
            string password = "";
            int passwordFormat = -1;
            string passwordSalt = "";
            int failedPasswordAttemptCount = -1;
            int failedPasswordAnswerAttemptCount = -1;
            bool isApproved = false;
            DateTime lastLoginDate = DateTime.Now;
            DateTime lastActivityDate = DateTime.Now;
 
            //get password data from database
            SeatAdmin.Classes.Global.ASPGetPasswordWithFormat("administrator", false, out status, out password, out passwordFormat, out passwordSalt, out failedPasswordAttemptCount, out failedPasswordAnswerAttemptCount, out isApproved, out lastLoginDate, out lastActivityDate);
 
            listBox1.Items.Add("status: " + status.ToString());
            listBox1.Items.Add("password: " + password);
            listBox1.Items.Add("passwordFormat: " + passwordFormat.ToString());
            listBox1.Items.Add("passwordSalt: " + passwordSalt);
            listBox1.Items.Add("failedPasswordAttemptCount: " + failedPasswordAttemptCount.ToString());
            listBox1.Items.Add("failedPasswordAnswerAttemptCount: " + failedPasswordAnswerAttemptCount.ToString());
            listBox1.Items.Add("isApproved: " + isApproved.ToString());
            listBox1.Items.Add("lastLoginDate: " + lastLoginDate.ToShortDateString());
            listBox1.Items.Add("lastActivityDate: " + lastActivityDate.ToShortDateString());
 
            //encrypt typed password
            string typedPasswordEncrypted = SeatAdmin.Classes.MyMembership.EncodePassword("adminpasshidden", Convert.ToByte(passwordFormat), passwordSalt);
            listBox1.Items.Add("mypass: " + typedPasswordEncrypted);
 
            if (typedPasswordEncrypted == password)
            {
                MessageBox.Show("Correct password");
            }
            else
            {
                MessageBox.Show("Incorrect password");
            }
        }

Open in new window