• Always set the "applicationName" property when configuring ASP.NET 2.0 Membership and other Providers


    Always set the "applicationName" property when configuring ASP.NET 2.0 Membership and other Providers 转载

    I helped out a few folks last night on the ASP.NET Forums with this problem, so I thought it might make sense to turn this into a blog post to help share information about this.

     

    Scenario:

     

    You develop an ASP.NET 2.0 application locally using the new ASP.NET 2.0 Membership, Roles or Profile features.  You create several new users and everything works fine.

     

    You then copy the application to a remote server (or even another directory on your local server) and run the application.  For some reason it appears that you are able to connect to your membership database just fine – but when you try to login it doesn’t let you.  It doesn’t throw a connection error, but rather when you attempt to login you get an error message that says something like: “Login attempt unsuccessful, please try again.”

     

    Cause:

     

    The reason this usually happens is because a membership (or roles or profile) provider has been added in the application’s web.config file – but without an applicationName attribute being specified (assume below that the applicationName in bold was missing):

     

          <membership>

                <providers>

                    <clear/>

                    <add name="AspNetSqlMembershipProvider"

                        type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"

                        connectionStringName="LocalSqlServer"

                        enablePasswordRetrieval="false"

                        enablePasswordReset="true"

                        requiresQuestionAndAnswer="true"

      requiresUniqueEmail="false"

                        passwordFormat="Hashed"

                        maxInvalidPasswordAttempts="5"

                        minRequiredPasswordLength="7"

                        minRequiredNonalphanumericCharacters="1"

                        passwordAttemptWindow="10"

                        passwordStrengthRegularExpression=""

                        applicationName="/"

                    />

                </providers>

          </membership>

     

    When no applicationName attribute is configured, ASP.NET uses the application vroot path within the web-server to automatically calculate the applicationName to use when adding data to an ASP.NET Application Service database.  To see this in action, you can open up your ASPNETDB database, and look within the aspnet_Applications table:

     

     

     

    This table stores a unique ApplicationID for each applicationName.  Because I didn’t specify an “applicationName” attribute when I registered users within my application, it calculated the application name as /website8 (which happened to be the name my dev machine was using at the time).

     

    Users created with the membership API will then be associated with this ApplicationID and in turn the applicationName.  You can see this by opening up the aspnet_Users table:

     

     

     

    This works fine when the application continues to run in the “/WebSite8” application virtual path.  But if it is copied to another location or server with a different virtual path (for example: “/app1” or more commonly just "/"), then when the Membership APIs are used they will not “see” the users already in our database – since they will lookup membership data using a different application name and filter the users in the application_Users table accordingly.  That is why you’ll get a “Login attempt unsuccessful, please try again.” message when you try to login.

     

    How to Solve This

     

    The easiest way to solve this is to open up the aspnet_Users and aspnet_Applications tables within the ASPNETDB database and figure out what application name was used when creating the users and other data during development (look in the aspnet_Application table to work this out).

     

    You can then go back to your web.config file, and add an “applicationName” attribute to your provider declaration with that application name value.  For example, note how the applicationName value below is now the same as the one in the aspnet_Application table:

     

          <membership>

                <providers>

                    <clear/>

                    <add name="AspNetSqlMembershipProvider"

                        type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"

                        connectionStringName="LocalSqlServer"

                        enablePasswordRetrieval="false"

                        enablePasswordReset="true"

                        requiresQuestionAndAnswer="true"

      requiresUniqueEmail="false"

                        passwordFormat="Hashed"

                        maxInvalidPasswordAttempts="5"

                        minRequiredPasswordLength="7"

                        minRequiredNonalphanumericCharacters="1"

                        passwordAttemptWindow="10"

                        passwordStrengthRegularExpression=""

                        applicationName="/website8"

                    />

                </providers>

          </membership>

     

    When the applicationName is set like above, the Membership API will always use that application name when connecting to the ASP.NET application service database.  That means it will work regardless of where the application is deployed or what path is used.

     

    You should also then make sure that you do this for any Roles, Profile, WebPartPersonalization or other providers you configure.

     

    Your application will then work fine.

     

    How to Prevent This in the First Place

     

    The best way to prevent this from ever happening is to always specify the “applicationName” attribute when declaring your providers.  One good default value to use is “/” – which is the root application name.  This is the value specified for the default provider that ships with ASP.NET 2.0 (which by default stores the application service data within the ASPNETDB.MDF file under /app_data), and is why if you don’t override the provider settings it will work if you copy an app to another machine.

     

    For other ASP.NET Security Links and Resources please check out (and bookmark) this large post of content I did.

     

    Hope this helps,

     

    Scott

     

    P.S. In case it isn’t obvious, the reason why the applicationName setting even exists in the first place is so that you can map multiple applications and sites to the same database.

     

    P.P.S. In hindsight, we should have defaulted the provider collection to have a value of "/" for applicationName if it wasn't specified.

  • 相关阅读:
    利用javascript的prototype来实现stirng类的扩展并实现string的insert方法
    利用笔记本共享WIFI热点及利用Android手机共享WIFI热点
    语言模型发展综述
    基于阻变存储器阵列的低功耗神经网络存算一体结构研究进展综述
    2021年度总结
    【20220102】连岳摘抄
    【20220103】攻城计
    【20220104】人生很长
    【20220106】带孩子看牙医
    【20220110】怀孕不是一个人的事情
  • 原文地址:https://www.cnblogs.com/stswordman/p/394852.html
Copyright © 2020-2023  润新知