none
How to share ASP.net Forms Authentication across several Silverlight websites

    Question

  • I have a situation where I am developing one or more Silverlight business apps but want them to share the same Forms Authentication database, so that users don't have to have separate usernames and passwords for each one.  What is the best way to do this?

    Thanks

    Patrick

    Tuesday, August 02, 2011 11:38 AM

Answers

  • Many thanks for all the comments.

    I managed to solve the problem and so thought I'd share the solution here:

    Essentially, I had to amend the Silverlight 4 Business App with Accent Theme web project's Web.config file

    to be similar to the standard Silverlight 4 Business App (i.e. standard theme) web project's Web.config file.

    The amendments were:

    • amending the AttachDBFilename= path in the ApplicationServices connection string to point to other project's aspnetdb.mdf file
    • expanding the roleManager and profile sections and adding a membership section in the web.config file, so that it matches that of the standard Silverlight 4 business application project.

    Here is the Web.config file:

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <configSections>
        <sectionGroup name="system.serviceModel">
          <section name="domainServices" type="System.ServiceModel.DomainServices.Hosting.DomainServicesSection, System.ServiceModel.DomainServices.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" allowDefinition="MachineToApplication" requirePermission="false" />
        </sectionGroup>
      </configSections>
      <system.web>
        <httpModules>
          <add name="DomainServiceModule" type="System.ServiceModel.DomainServices.Hosting.DomainServiceHttpModule, System.ServiceModel.DomainServices.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
        </httpModules>
        <compilation debug="true" targetFramework="4.0">
          <assemblies>
            <add assembly="System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
          </assemblies>
        </compilation>
        
        <!-- PJL 03 Sep 2011 commented out because will be replaced by expanded roleManager section below
        <roleManager enabled="true" />
        -->
    
        <authentication mode="Forms">
          <forms name=".SLBusAppAccentTheme1_ASPXAUTH" />
        </authentication>
        <!-- PJL 03 Sep 2011 commented out because will be replaced by expanded profile section below    
        <profile>
          <properties>
            <add name="FriendlyName" />
          </properties>
        </profile>
        -->
    
        <!-- 03 Sep 2011 added, as per the configuration of a Silverlight 4 Business App (without themes) -->
        <membership>
          <providers>
            <clear/>
            <add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="ApplicationServices"
                 enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false"
                 maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10"
                 applicationName="/" />
          </providers>
        </membership>
        <roleManager enabled="true">
          <providers>
            <clear/>
            <add name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="ApplicationServices" applicationName="/" />
            <add name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider" applicationName="/" />
          </providers>
        </roleManager>
        <profile>
          <providers>
            <clear/>
            <add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="ApplicationServices" applicationName="/"/>
          </providers>
          <properties>
            <add name="FriendlyName"/>
          </properties>
        </profile>
    
      </system.web>
      <system.webServer>
        <validation validateIntegratedModeConfiguration="false" />
        <modules runAllManagedModulesForAllRequests="true">
          <add name="DomainServiceModule" preCondition="managedHandler" type="System.ServiceModel.DomainServices.Hosting.DomainServiceHttpModule, System.ServiceModel.DomainServices.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
        </modules>
      </system.webServer>
      <system.serviceModel>
        <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
      </system.serviceModel>
      <connectionStrings>
        <add name="TestFinPlanner1Entities" connectionString="metadata=res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl;provider=System.Data.SqlClient;provider connection string=&quot;Data Source=localhost\sqlexpress;Initial Catalog=TestFinPlanner1;Integrated Security=True;MultipleActiveResultSets=True&quot;" providerName="System.Data.EntityClient" />
    
        <!-- 03 Aug 2011 PJL added and amended from the default to use authentication database from the SLBusAppCosmoTheme project  
        <add name="ApplicationServices"
          connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnetdb.mdf;User Instance=true"
          providerName="System.Data.SqlClient" />
          -->
        <add name="ApplicationServices"
         connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=C:\Users\PJL\Documents\Devs\Tests4\SLBusAppCosmoTheme\SLBusAppCosmoTheme.Web\App_Data\aspnetdb.mdf;User Instance=true"
         providerName="System.Data.SqlClient" />
    
      </connectionStrings>
    </configuration>
    

    Thursday, September 15, 2011 11:25 AM

All replies

  • The website(s) that you are developing need to point to the same instance of database but other than that there should be no issues.  If you are using the standard SQL providers then just make sure the connection strings for authentication are all the same for the different websites.

     

    If you are hosting all your Silverlight applications on the same website then you may need to consider how this will work in terms of a user experience.  If a user chooses to persist their login then logging into one business application will mean they automatically get logged into the other business applications when loading them if you are using the browser based model (BrowserHttp).  If you are using ClientHttp then you will need to manage the authentication cookies manually.  BrowserHttp is the default model that Silverlight uses and can be managed through the WebRequest class (There are blogs out there that expalin this)  In short BrowserHttp has the internet browser manage the cookies, and ClientHttp has Silverlight manage them directly.  All this being said it may not be something you need to care about.

     

    Tuesday, August 02, 2011 6:13 PM
  • Many thanks for the reply, BofC.  I can see how to set the connection string appropriately in Silverlight projects (e.g. from the standard Visual Studio 2010 Silverlight Business App template) where the Web.config contains a place where the connection string for "ApplicationServices" is explicitly set

     <connectionStrings>
    <add name="ApplicationServices"
    connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;
    AttachDBFilename=|DataDirectory|\aspnetdb.mdf;User Instance=true"
    providerName="System.Data.SqlClient" />
    </connectionStrings>

    However, not all the Silverlight business app templates seem to do this, e.g. in a project created from the 
    "Silverlight Business Application (Cosmopolitan Theme)" template, the Web.config file doesn't contain any such 
    connection string for authentication. Any idea why that is (perhaps if no string is specified, websites still use 
    |DataDirectory|\aspnetdb.mdf by default?), and how such projects can be configured to use an explicit 
    connectionString to connect to the desired authentication database? 
    
    
    (Edited 03 Sep 2011 to correct line layout: for some reason lines weren't wrapping so only some of the text I had entered
    was visible!)
    
    
    
    
    Thursday, August 04, 2011 1:01 PM
  • I don't really use Application (or RIA) services tbh.  You should be able to set the connection that a particular provider uses in the provider sections.  e.g.

    <add name="AspNetSqlRoleProvider" applicationName="/MyApplication" connectionStringName="StandardConnectionString" type="System.Web.Security.SqlRoleProvider" />

    Replace 'StandardConnectionString' with whatever the name of your connection is (ApplicationServices in this case)

    Thursday, August 04, 2011 9:14 PM
  • Thanks - I've tried adding code such as the following to the Web.config file for the Silverlight Business App with Accent Theme web project:

    <!-- 07 Aug 2011 added to try using authentication database from the other project  -->
        <membership defaultProvider="AspNetMembershipProvider">
          <providers>
            <clear/>        
        <add name="AspNetMembershipProvider" applicationName="/MyApplication" connectionStringName="ApplicationServices" type="System.Web.Security.MembershipProvider" />
          </providers>
        </membership>
        <roleManager enabled="true">
          <providers>
            <clear/>
            <add name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="ApplicationServices" applicationName="/" />
            <add name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider" applicationName="/" />
          </providers>
        </roleManager>
    
    
    but I get the following error messages (depending on what providers I try and add above) when trying to log in:
    
    
    Load operation failed for query 'Login'. Provider must implement the class 
    'System.Web.Security.MembershipProvider'or else "cannot implement abstract class"
    
    
    Any help gratefully received!
    
    
    (Edited 03 Sep 2011 because, as with my previous post, lines weren't wrapping properly, so put the code 
    extract in again via "Insert code" facility)
    Saturday, August 06, 2011 11:58 PM
  • Hi,

    In HTML5 + MV3 we can have multipla web.config.

    Sunday, August 07, 2011 3:45 PM
  • Hi Patrick,

    For the membership provider you are not using a concrete implementation, but the abstract membership provider class, you need to provide it with a concrete version. 

    If you are using forms authentication this would be System.Web.Security.SqlMembershipProvider in the System.Web library.  (e.g.)

    <add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" 
                 connectionStringName="StandardConnectionString" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="true" 
                 applicationName="/MyApplication" requiresUniqueEmail="true" passwordFormat="Hashed" maxInvalidPasswordAttempts="100" passwordAttemptWindow="10" 
                 passwordStrengthRegularExpression="^(?=.+\d)[\w\-]{6,12}$" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" />
    Sunday, August 07, 2011 5:04 PM
  • You might also want to get rid of the AspNetWindowsTokenRole provider as I believe this is for windows based security, not forms security which you have stated you are using in your thread title.

    Sunday, August 07, 2011 5:05 PM
  • Many thanks for all the comments.

    I managed to solve the problem and so thought I'd share the solution here:

    Essentially, I had to amend the Silverlight 4 Business App with Accent Theme web project's Web.config file

    to be similar to the standard Silverlight 4 Business App (i.e. standard theme) web project's Web.config file.

    The amendments were:

    • amending the AttachDBFilename= path in the ApplicationServices connection string to point to other project's aspnetdb.mdf file
    • expanding the roleManager and profile sections and adding a membership section in the web.config file, so that it matches that of the standard Silverlight 4 business application project.

    Here is the Web.config file:

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <configSections>
        <sectionGroup name="system.serviceModel">
          <section name="domainServices" type="System.ServiceModel.DomainServices.Hosting.DomainServicesSection, System.ServiceModel.DomainServices.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" allowDefinition="MachineToApplication" requirePermission="false" />
        </sectionGroup>
      </configSections>
      <system.web>
        <httpModules>
          <add name="DomainServiceModule" type="System.ServiceModel.DomainServices.Hosting.DomainServiceHttpModule, System.ServiceModel.DomainServices.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
        </httpModules>
        <compilation debug="true" targetFramework="4.0">
          <assemblies>
            <add assembly="System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
          </assemblies>
        </compilation>
        
        <!-- PJL 03 Sep 2011 commented out because will be replaced by expanded roleManager section below
        <roleManager enabled="true" />
        -->
    
        <authentication mode="Forms">
          <forms name=".SLBusAppAccentTheme1_ASPXAUTH" />
        </authentication>
        <!-- PJL 03 Sep 2011 commented out because will be replaced by expanded profile section below    
        <profile>
          <properties>
            <add name="FriendlyName" />
          </properties>
        </profile>
        -->
    
        <!-- 03 Sep 2011 added, as per the configuration of a Silverlight 4 Business App (without themes) -->
        <membership>
          <providers>
            <clear/>
            <add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="ApplicationServices"
                 enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false"
                 maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10"
                 applicationName="/" />
          </providers>
        </membership>
        <roleManager enabled="true">
          <providers>
            <clear/>
            <add name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="ApplicationServices" applicationName="/" />
            <add name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider" applicationName="/" />
          </providers>
        </roleManager>
        <profile>
          <providers>
            <clear/>
            <add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="ApplicationServices" applicationName="/"/>
          </providers>
          <properties>
            <add name="FriendlyName"/>
          </properties>
        </profile>
    
      </system.web>
      <system.webServer>
        <validation validateIntegratedModeConfiguration="false" />
        <modules runAllManagedModulesForAllRequests="true">
          <add name="DomainServiceModule" preCondition="managedHandler" type="System.ServiceModel.DomainServices.Hosting.DomainServiceHttpModule, System.ServiceModel.DomainServices.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
        </modules>
      </system.webServer>
      <system.serviceModel>
        <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
      </system.serviceModel>
      <connectionStrings>
        <add name="TestFinPlanner1Entities" connectionString="metadata=res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl;provider=System.Data.SqlClient;provider connection string=&quot;Data Source=localhost\sqlexpress;Initial Catalog=TestFinPlanner1;Integrated Security=True;MultipleActiveResultSets=True&quot;" providerName="System.Data.EntityClient" />
    
        <!-- 03 Aug 2011 PJL added and amended from the default to use authentication database from the SLBusAppCosmoTheme project  
        <add name="ApplicationServices"
          connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnetdb.mdf;User Instance=true"
          providerName="System.Data.SqlClient" />
          -->
        <add name="ApplicationServices"
         connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=C:\Users\PJL\Documents\Devs\Tests4\SLBusAppCosmoTheme\SLBusAppCosmoTheme.Web\App_Data\aspnetdb.mdf;User Instance=true"
         providerName="System.Data.SqlClient" />
    
      </connectionStrings>
    </configuration>
    

    Thursday, September 15, 2011 11:25 AM