2010-02-09 47 views
0

我有一個asp.net網絡應用程序,它使用基於表單的身份驗證,SqlMembershipProvider(使用加密的密碼格式),和一個SqlRoleProvider。我需要知道是否可以從Windows應用程序管理用戶(創建新用戶,將它們分配給角色等) - 這些權力不需要Web應用程序本身的任何管理功能。從windows應用程序管理asp.net網站(創建新用戶,分配用戶到角色等)

這裏是web.config中的成員資格提供定義:

<membership defaultProvider="MyProvider"> 
    <providers> 
    <add name="MyProvider" 
     type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" 
     connectionStringName="MyConnectionString" 
     enablePasswordRetrieval="false" 
     enablePasswordReset="true" 
     requiresQuestionAndAnswer="true" 
     applicationName="/MyWebApp" 
     requiresUniqueEmail="true" 
     passwordFormat="Encrypted" 
     maxInvalidPasswordAttempts="5" 
     minRequiredPasswordLength="7" 
     minRequiredNonalphanumericCharacters="1" 
     passwordAttemptWindow="10" 
     passwordStrengthRegularExpression=""/> 
    </providers> 
</membership> 

和角色管理器定義:

<roleManager enabled="true" defaultProvider="MyRoleManager"> 
    <providers> 
    <add name="MyRoleManager" 
     type="System.Web.Security.SqlRoleProvider" 
     connectionStringName="MyConnectionString" 
     applicationName="/MyWebApp" /> 
    </providers> 
</roleManager> 

這裏是(必要的machineKey定義爲能夠使用加密口令):

<machineKey 
    validationKey="BC50A82A6AF6A015C34C7946D29B817C00F04D2AB10BC2128D1E2433D0E365E426E57337CECAE9A0681A2C736B9779B42F75D60F09F142C60E9E0E8F9840DB46" 
     decryptionKey="122035576C5476DCD8F3611954C837CDA5FE33BCDBBF23F7" 
     validation="SHA1" 
     decryption="AES"/> 

所以,顯然,我有一個Sql Server數據庫臨時t包含Web應用程序的用戶和角色。我想創建一個引用Web應用程序組件的獨立Windows應用程序,並使用配置的MembershipProvider,RoleProvider和machineKey創建用戶,將用戶分配給角色等。如果這不可行,我可以將配置設置從web應用程序中的web.config。但我也不知道該怎麼做。

我是不是認爲這有可能?我試過Google搜索解決方案,但信噪比非常糟糕。

回答

2

我想出了一個解決方案,基於其他答案(誰都得到了+1)和some othersitesout there

首先,我創建了應用程序配置文件(app.config)。它反映究竟是什麼從Web應用程序的web.config中發現,隨着連接字符串是如何處理的異常:

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 

    <configSections> 
    <section name="connectionStrings" type="System.Configuration.ConnectionStringsSection, System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" requirePermission="false" /> 
    </configSections> 

    <connectionStrings> 
    <add name="MyConnectionString" 
     connectionString ="SERVER=abc;UID=def;PWD=hij;Initial Catalog=klm;MultipleActiveResultsets=True"/> 
    </connectionStrings> 

    <system.web> 

    <membership defaultProvider="MySqlMembershipProvider"> 
     <providers> 
     <add name="MySqlMembershipProvider" 
      type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" 
      connectionStringName="MyConnectionString" 
      enablePasswordRetrieval="false" 
      enablePasswordReset="true" 
      requiresQuestionAndAnswer="true" 
      applicationName="/MyWebApp" 
      requiresUniqueEmail="true" 
      passwordFormat="Encrypted" 
      maxInvalidPasswordAttempts="5" 
      minRequiredPasswordLength="7" 
      minRequiredNonalphanumericCharacters="1" 
      passwordAttemptWindow="10" 
      passwordStrengthRegularExpression=""/> 
     </providers> 
    </membership> 

    <roleManager enabled="true" defaultProvider="MySqlRoleManager"> 
     <providers> 
     <add name="MySqlRoleManager" 
      type="System.Web.Security.SqlRoleProvider" 
      connectionStringName="MyConnectionString" 
      applicationName="/MyWebApp" /> 
     </providers> 
    </roleManager> 

    <machineKey 
     validationKey="BC50A82A6AF6A015C34C7946D29B817C00F04D2AB10BC2128D1E2433D0E365E426E57337CECAE9A0681A2C736B9779B42F75D60F09F142C60E9E0E8F9840DB46" 
     decryptionKey="122035576C5476DCD8F3611954C837CDA5FE33BCDBBF23F7" 
     validation="SHA1" 
     decryption="AES"/> 
    </system.web> 

</configuration> 

然後我創建了一個助手類,它提供了兩個單身訪問:一個MembershipProviderRoleProvider。事實證明,這是更容易比我想象,一旦我知道如何做到這一點:

using System.Configuration; 
using System.Reflection; 
using System.Web.Security; 

namespace WebAdminViaWindows 
{ 
    internal static class Provider 
    { 
     private static readonly string assemblyFilePath = Assembly.GetExecutingAssembly().Location; 

     static Provider() 
     { 
      Membership = CreateMembershipProvider(); 
      Role = CreateRoleProvider(); 
     } 

     public static MembershipProvider Membership { get; private set; } 
     public static RoleProvider Role { get; private set; } 

     private static MembershipProvider CreateMembershipProvider() 
     { 
      var config = ConfigurationManager.OpenExeConfiguration(assemblyFilePath); 

      var systemWebGroup = config.SectionGroups["system.web"]; 
      if (systemWebGroup == null) 
      { 
       throw new ConfigurationErrorsException("system.web group not found in configuration"); 
      } 

      var membershipSection = systemWebGroup.Sections["membership"]; 
      if (membershipSection == null) 
      { 
       throw new ConfigurationErrorsException("membership section not found in system.web group"); 
      } 

      var defaultProviderProperty = membershipSection.ElementInformation.Properties["defaultProvider"]; 
      if (defaultProviderProperty == null) 
      { 
       throw new ConfigurationErrorsException("defaultProvider property not found in membership section"); 
      } 

      var defaultProviderName = defaultProviderProperty.Value as string; 
      if (defaultProviderName == null) 
      { 
       throw new ConfigurationErrorsException("defaultProvider property is not a string value"); 
      } 

      var providersProperty = membershipSection.ElementInformation.Properties["providers"]; 
      if (providersProperty == null) 
      { 
       throw new ConfigurationErrorsException("providers property not found in membership section"); 
      } 

      var providerCollection = providersProperty.Value as ProviderSettingsCollection; 
      if (providerCollection == null) 
      { 
       throw new ConfigurationErrorsException("providers property is not an instance of ProviderSettingsCollection"); 
      } 

      ProviderSettings membershipProviderSettings = null; 

      foreach (ProviderSettings providerSetting in providerCollection) 
      { 
       if (providerSetting.Name == defaultProviderName) 
       { 
        membershipProviderSettings = providerSetting; 
       } 
      } 

      if (membershipProviderSettings == null) 
      { 
       if (providerCollection.Count > 0) 
       { 
        membershipProviderSettings = providerCollection[0]; 
       } 
       else 
       { 
        throw new ConfigurationErrorsException("No providers found in configuration"); 
       } 
      } 

      var provider = new SqlMembershipProvider(); 
      provider.Initialize("MySqlMembershipProvider", membershipProviderSettings.Parameters); 
      return provider; 
     } 

     private static RoleProvider CreateRoleProvider() 
     { 
      var config = ConfigurationManager.OpenExeConfiguration(assemblyFilePath); 

      var systemWebGroup = config.SectionGroups["system.web"]; 
      if (systemWebGroup == null) 
      { 
       throw new ConfigurationErrorsException("system.web group not found in configuration"); 
      } 

      var roleManagerSection = systemWebGroup.Sections["roleManager"]; 
      if (roleManagerSection == null) 
      { 
       throw new ConfigurationErrorsException("roleManager section not found in system.web group"); 
      } 

      var defaultProviderProperty = roleManagerSection.ElementInformation.Properties["defaultProvider"]; 
      if (defaultProviderProperty == null) 
      { 
       throw new ConfigurationErrorsException("defaultProvider property not found in roleManager section"); 
      } 

      var defaultProviderName = defaultProviderProperty.Value as string; 
      if (defaultProviderName == null) 
      { 
       throw new ConfigurationErrorsException("defaultProvider property is not a string value"); 
      } 

      var providersProperty = roleManagerSection.ElementInformation.Properties["providers"]; 
      if (providersProperty == null) 
      { 
       throw new ConfigurationErrorsException("providers property not found in roleManagerSection section"); 
      } 

      var providerCollection = providersProperty.Value as ProviderSettingsCollection; 
      if (providerCollection == null) 
      { 
       throw new ConfigurationErrorsException("providers property is not an instance of ProviderSettingsCollection"); 
      } 

      ProviderSettings roleProviderSettings = null; 

      foreach (ProviderSettings providerSetting in providerCollection) 
      { 
       if (providerSetting.Name == defaultProviderName) 
       { 
        roleProviderSettings = providerSetting; 
       } 
      } 

      if (roleProviderSettings == null) 
      { 
       if (providerCollection.Count > 0) 
       { 
        roleProviderSettings = providerCollection[0]; 
       } 
       else 
       { 
        throw new ConfigurationErrorsException("No providers found in configuration"); 
       } 
      } 

      var provider = new SqlRoleProvider(); 
      provider.Initialize("MySqlRoleManager", roleProviderSettings.Parameters); 
      return provider; 
     } 
    } 
} 

此時所有的需要是訪問Provider類的MembershipRole性能。作爲一個例子,下面的打印出前10組的用戶和他們的角色:

int total; 
foreach (MembershipUser user in Provider.Membership.GetAllUsers(0, 10, out total)) 
{ 
    var sb = new StringBuilder(); 
    sb.AppendLine(user.UserName); 
    foreach (var role in Provider.Role.GetRolesForUser(user.UserName)) 
    { 
     sb.AppendLine("\t" + role); 
    } 

    Console.WriteLine(sb.ToString()); 
} 
+0

令人印象深刻。我沒有意識到這可能很簡單。 –

1

我不確定這裏會有什麼「最佳實踐」,但應該工作的一個簡單方法就是這樣。

  • 創建一個新的Windows應用程序
  • (從上面 ^設置)
  • 添加添加應用程序配置文件 (app.config)中
  • 複製適當的設置到 在app.config參考System.Web
  • 並將您的網絡應用 中的代碼複製到使用上述設置的 連接到數據庫

這應該做你想做的。

+0

我可以實例的SqlMembershipProvider和SqlRoleProvider並設置*幾乎*所有必要的屬性,但我怎麼給他們一個連接字符串?我將如何向SqlMembershipProvider提供驗證和解密密鑰? – fre0n

+0

根據http://msdn.microsoft.com/en-us/library/system.web.security.sqlmembershipprovider_members.aspx,沒有屬性或方法來設置SqlMembershipProvider的連接字符串。 – fre0n

+0

您應該可以像在您的網絡應用程序中那樣執行所有操作。我假設你在你的網絡應用中使用類似的代碼讓用戶登錄? – TJMonk15

2

一些選項:

  • 你可以使用Web Site Administration Tool,這是不 Windows的基於表單的,而不是你的Web應用程序的一部分 ,無論是。它帶有Visual Studio的 ,可以通過單擊解決方案 Explorer中的ASP.NET 配置圖標訪問 。
  • 它可以直接操縱 從Windows 窗體應用程序使用一個 SqlMembershipProvider的供應商數據庫,但你可能必須要 小心,不要打破東西。
  • 如果您要創建自定義 成員資格提供程序,您將會在 控制成員資格和角色 數據如何持續。如果你這樣做了 ,你可以創建一個可重用的庫 ,它可以在Web應用程序中使用,也可以在Windows Forms應用程序中使用 。

我不認爲試圖從Windows窗體應用程序使用SqlMembershipProvider是一種實用的方法。

+0

它適用於VS,但是您可以在生產環境中使用網站管理工具嗎? – fre0n

+0

@ fre0n:技術上是的,但並不簡單。這裏描述:http://forums.asp.net/p/932674/1155428.aspx我會看看我提到的其他選項。 –

+0

這是一個很好的建議......你最好的選擇就是輕鬆做到這一點。否則,你最好創建自己的會員和角色提供者。 – Bryan

相關問題