Solved

Using SqlMembershipProvider in desktop application

Posted on 2008-10-06
13
2,240 Views
Last Modified: 2008-10-07
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.
0
Comment
Question by:dbrckovi
  • 7
  • 6
13 Comments
 
LVL 96

Expert Comment

by:Bob Learned
ID: 22650050
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.
0
 
LVL 11

Author Comment

by:dbrckovi
ID: 22650713
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

0
 
LVL 11

Author Comment

by:dbrckovi
ID: 22650729
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.
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 22650751
What does ex.ToString equal?
0
 
LVL 11

Author Comment

by:dbrckovi
ID: 22650780
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
0
 
LVL 11

Author Comment

by:dbrckovi
ID: 22650850
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

0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 96

Expert Comment

by:Bob Learned
ID: 22651033
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

0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 22651080
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

0
 
LVL 11

Author Comment

by:dbrckovi
ID: 22651203
Thank you!

GetPasswordWithFormat looks like exactly what I need. I will try it a bit later and post back the results.
0
 
LVL 11

Author Comment

by:dbrckovi
ID: 22659259
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.
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 22659284
I feel like the game today is "Stump the Expert".  I have no idea about that algorithm. :(
0
 
LVL 96

Accepted Solution

by:
Bob Learned earned 500 total points
ID: 22659323
The underlying MembershipProvider class, which the SqlMembershipProvider inherits from, does provide a method:

protected virtual byte[] EncryptPassword(byte[] password)

I believe that this means that it is only available to inheriting classes, and not the SqlMembershipProvider.  I see some examples, where someone has added another inheritance layer, like this:

Encrypt Password in Membership Provider - Help MVP! - ASP.NET Forums
http://forums.asp.net/t/1265971.aspx

public class MyMembership : SqlMembershipProvider
{

    public override byte[] EncryptPassword(byte[] password)
    {
     }
}
0
 
LVL 11

Author Comment

by:dbrckovi
ID: 22659758
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

0

Featured Post

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Extention Methods in C# 3.0 by Ivo Stoykov C# 3.0 offers extension methods. They allow extending existing classes without changing the class's source code or relying on inheritance. These are static methods invoked as instance method. This…
Introduction This article series is supposed to shed some light on the use of IDisposable and objects that inherit from it. In essence, a more apt title for this article would be: using (IDisposable) {}. I’m just not sure how many people would ge…
In this tutorial you'll learn about bandwidth monitoring with flows and packet sniffing with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're interested in additional methods for monitoring bandwidt…
You have products, that come in variants and want to set different prices for them? Watch this micro tutorial that describes how to configure prices for Magento super attributes. Assigning simple products to configurable: We assigned simple products…

706 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now