简体   繁体   English

从Windows应用程序管理asp.net网站(创建新用户,将用户分配给角色等)

[英]Administer asp.net website (create new users, assign users to roles, etc.) from a windows app

I have an asp.net web app that uses forms-based authentication, a SqlMembershipProvider (using an encrypted password format), and a SqlRoleProvider. 我有一个使用基于表单的身份验证的asp.net Web应用程序,一个SqlMembershipProvider(使用加密的密码格式)和一个SqlRoleProvider。 I need to know if it's possible to administer the users (create new users, assign them to roles, etc.) from a windows application - the powers that be don't want any administrative functionality in the web app itself. 我需要知道是否有可能通过Windows应用程序来管理用户(创建新用户,将他们分配给角色,等等)-这些功能不希望Web应用程序本身具有任何管理功能。

Here is the membership provider definition from web.config: 这是来自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>

And the role manager definition: 以及角色管理器的定义:

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

And here is the machineKey definition (necessary to be able to use encrypted passwords): 这是machineKey定义(必须能够使用加密的密码):

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

So, obviously, I have a Sql Server database that contains the users and roles for the web app. 因此,显然,我有一个Sql Server数据库,其中包含Web应用程序的用户和角色。 I'd like to create a separate windows app that references the web app assembly, and use the configured MembershipProvider, RoleProvider, and machineKey to create users, assign users to roles, etc. If that's not possible, I can duplicate the configuration settings from web.config within the windows app. 我想创建一个引用该Web应用程序集的单独的Windows应用程序,并使用配置的MembershipProvider,RoleProvider和machineKey来创建用户,将用户分配给角色等。如果不可能,我可以从Windows应用程序中的web.config。 But I don't know how to do this either. 但是我也不知道该怎么做。

Am I way out of line thinking that this is possible? 我是否认为这是可能的? I've tried googling for a solution, but the signal-to-noise ratio is really bad. 我曾尝试使用谷歌搜索解决方案,但信噪比确实很差。

Some options: 一些选项:

  • You could use the Web Site Administration Tool , which isn't Windows-Forms-based, but isn't part of your Web app, either. 您可以使用网站管理工具 ,它也不是基于Windows窗体的,但也不是您的Web应用程序的一部分。 It comes with Visual Studio and can be accessed by clicking the ASP.NET Configuration icon in the Solution Explorer. 它随Visual Studio一起提供,可以通过单击解决方案资源管理器中的“ ASP.NET配置”图标进行访问。
  • It's possible to directly manipulate the provider database used by a SqlMembershipProvider from a Windows Forms app, but you might have to be careful not to break things. 可以从Windows Forms应用程序直接操作SqlMembershipProvider使用的提供程序数据库,但是您可能必须小心,不要破坏事情。
  • If you were to create a custom membership provider, you'd be in control of how membership and role data is persisted. 如果要创建自定义成员资格提供程序,则可以控制成员资格和角色数据的持久保存方式。 If you did that you could create a reusable library that could be used in the Web app and a Windows Forms app, too. 如果这样做,则可以创建可在Web应用程序和Windows Forms应用程序中使用的可重用库。

I don't think trying to use a SqlMembershipProvider from a Windows Forms app is a practical approach. 我不认为尝试从Windows Forms应用程序使用SqlMembershipProvider是一种实用的方法。

I've come up with a solution, based on the other answers (who both got +1), and some other sites out there . 我想出了一个解决方案,基于其他答案(谁俩都+1),以及其他一些 网站 在那里

First, I created Application Config file (app.config). 首先,我创建了应用程序配置文件(app.config)。 It mirrors exactly what is found in web.config from the web app, with the exception of how the connection string was handled: 它完全反映了从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>

Then I created a helper class that provides access to two singletons: a MembershipProvider and a RoleProvider . 然后,我创建了一个帮助程序类,该类提供对两个单例的访问: MembershipProviderRoleProvider This turned out to be easier than I thought, once I knew how to do it: 一旦知道如何做,这比我想的要容易:

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;
        }
    }
}

At this point all that's needed is to access the Membership and Role properties of the Provider class. 此时,所需要做的就是访问Provider类的MembershipRole属性。 As an example, the following prints out the first 10 users and their roles: 例如,以下内容打印出前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());
}

I'm not sure what "best-practice" would be here, but a simple way that should work is this. 我不知道什么是“最佳实践”会在这里,但应该运行的一个简单的方法是这样的。

  • Make a new windows app 制作一个新的Windows应用
  • Add an Application Config file (app.config) 添加一个应用程序配置文件(app.config)
  • Copy the appropriate settings into the app.config (settings from above ^) 将适当的设置复制到app.config中(^上方的设置)
  • Add a reference to System.Web 添加对System.Web的引用
  • And copy the code from your web app that uses the above settings to connect to the database 并从使用上述设置的Web应用程序中复制代码以连接到数据库

That should do what you want. 那应该做你想要的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM