What happened to my ValidateUser request for membership? (using ClientFormsAuthenticationMembershipProvider)

Is there any simple diagnostics I can run to determine why authentication is not working with the ClientFormsAuthenticationMembershipProvider? My problem:

I have a website (we'll call it the "Authenticator" website) hosted on Server A that is configured to use the AspNetSqlMembershipProvider to manage membership and roles. I believe the relevant web.config keys for this website are:

    <membership>
        <providers>
            <clear />
            <add name="AspNetSqlMembershipProvider"
                 type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
                 connectionStringName="MMMS35.API"
                 enablePasswordRetrieval="false"
                 enablePasswordReset="true"
                 requiresQuestionAndAnswer="false"
                 applicationName="Moose"
                 requiresUniqueEmail="false"
                 passwordFormat="Hashed"
                 maxInvalidPasswordAttempts="5"
                 minRequiredPasswordLength="7"
                 minRequiredNonalphanumericCharacters="0"
                 passwordAttemptWindow="1"
                 passwordStrengthRegularExpression="" />
        </providers>
    </membership>
    <profile>
        <providers>
            <clear />
            <add name="AspNetSqlProfileProvider"
                 connectionStringName="MMMS35.API"
                 applicationName="Moose"
                 type="System.Web.Profile.SqlProfileProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
        </providers>
    </profile>
    <roleManager enabled="true">
        <providers>
            <clear />
            <add name="AspNetSqlRoleProvider"
                 connectionStringName="MMMS35.API"
                 applicationName="Moose"
                 type="System.Web.Security.SqlRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
        </providers>
    </roleManager>

      

I have another website (called the "Test Client" website) hosted on Server B on the same network as Server A, but I have an idea of ​​what the network paths, router configuration, etc. ... are between Servers A and B. The client under test has a login mock that uses the ClientFormsAuthenticationMembershipProvider to ask the Authenticator website to authenticate the credentials given to the test client. The relevant sections of the test client web.config are as follows:

    <membership defaultProvider="ClientAuthenticationMembershipProvider">
        <providers>
            <clear/>
            <add name="ClientAuthenticationMembershipProvider"
                 type="System.Web.ClientServices.Providers.ClientFormsAuthenticationMembershipProvider, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                 serviceUri="http://slmooseapp1/mia/Authentication_JSON_AppService.axd"
                 credentialsProvider=""
                 savePasswordHashLocally="False"/>
        </providers>
    </membership>
    <roleManager defaultProvider="ClientRoleProvider" enabled="true">
        <providers>
            <clear/>
            <add name="ClientRoleProvider"
                 type="System.Web.ClientServices.Providers.ClientRoleProvider, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                 serviceUri="http://slmooseapp1/mia/Role_JSON_AppService.axd"
                 cacheTimeout="1"/>
        </providers>
    </roleManager>

      

When the test client runs this line:

DirectCast(Membership.Provider, ClientServices.Providers.ClientFormsAuthenticationMembershipProvider).ValidateUser(UserName.Text, Password.Text)

      

I am getting an exception:

System.UnauthorizedAccessException: Access to the path 'C:\Documents and Settings\Default User\Application Data\Microsoft Corporation\Internet Information Services\6.0.3790.3959' is denied.

      

However, when I run the test client in my development box (not server B) using the same web.config serviceUri paths (i.e. my client membership provider points to the same authentication website on server A) , authenticating a user and getting a role for that user works fine.

If I open a browser on Server B and request a page from the Authentication website, the Authentication web app works fine, so I know that I can successfully complete the HTTP requests from Server B to Server A. What happens to the ClientFormsAuthenticationMembershipProvider that fails when it tries to make (as it seems to me) a JSON request from server B to server A?

EDIT (9/21/2009):

I tried this scenario now from the Authentication website and Test Client on the same box (which is not my development machine). It still doesn't work. I wrote a raw Http request programmatically and the DID got a successful response ...

Request:

Content-Type: application/json
Host: slappdev
Content-Length: 70
Expect: 100-continue
Connection: Keep-Alive

{"userName":"mdh","password":"test123","createPersistentCookie":false}

      

Answer:

MicrosoftOfficeWebServer: 5.0_Pub
Content-Length: 10
Cache-Control: private, max-age=0
Content-Type: application/json; charset=utf-8
Date: Mon, 21 Sep 2009 20:10:13 GMT
Set-Cookie: AppName=1756811D52C4619AC78...; path=/; HttpOnly
Server: Microsoft-IIS/6.0
X-AspNet-Version: 2.0.50727
X-Powered-By: ASP.NET

{"d":true}

      

So, I'm guessing something is wrong, working through calls to framework.Net to get the actual HTTP request from ValidateUser. Any ideas?

Edit (9/22/2009) :

The thrown exception is the same exception that is thrown when my test client web page tries to access System.Windows.Forms.Application.UserAppDataPath. Adding the connectionStringName attribute to the member / providers / add key pointing to the correct connection string name in the web.config file in the client web application changes the exception!

System.Data.SqlClient.SqlException: Invalid object name 'ApplicationProperties'. at System.Data.SqlClient.SqlConnection.OnError

      

So if all membership functions use serviceUri, why are all attempts done locally on the client? And what utility do I need to run to add these new tables / objects to my database to support the client membership provider?

+2


source to share


2 answers


ClientAuthenticationMembershipProvider has an offline cache feature. If the actual membership provider cannot be reached, the tenant membership provider can cache the credentials on the client computer and use those offline credentials. This offline cache is represented by a SQL Server Compact Edition database file that is automatically generated and stored in the System.Windows.Forms.Application.UserAppDataPath location.

According to this MSDN article , you can set up a local offline cache to use the database. You have to manually create the database tables as mentioned in the article (in my 9/22 revision, I haven't created these tables yet, and there is no usefulness for that). I did this, but the client still wanted to create a local machine folder structure for the local SQL CE file, even if it never creates such a file. For every machine in my EXCEPT testing of my local workstation, the IIS user did not have access to the assembly of this folder structure for the local cache database, which threw an UnauthorizedAccessException.



I am rather unhappy that A) there is no config key to disable offline cache for membership, and B) even when offline cache is running with the database, the client membership provider still has to create a folder path for the local cache file it never does not create.

+2


source


If you add the system.diagnostic tag to your web.config file it works. (I only get an empty file here, but also no error message.)



 <system.diagnostics>
        <sources>
            <!-- This section defines the logging configuration for My.Application.Log -->
            <source name="DefaultSource" switchName="DefaultSwitch">
                <listeners>
                    <add name="myListener"/>
                    <!-- Uncomment the below section to write to the Application Event Log -->
                    <!--<add name="EventLog"/>-->
                </listeners>
            </source>
        </sources>
        <switches>
            <add name="DefaultSwitch" value="Information" />
        </switches>
        <sharedListeners>
          <add    name="myListener"
                       type="System.Diagnostics.TextWriterTraceListener"
                       initializeData="c:\temp\MyFile.log" />
            <!-- Uncomment the below section and replace APPLICATION_NAME with the name of your application to write to the Application Event Log -->
            <!--<add name="EventLog" type="System.Diagnostics.EventLogTraceListener" initializeData="APPLICATION_NAME"/> -->
        </sharedListeners>
    </system.diagnostics>

      

0


source







All Articles