【问题标题】:Is it possible to use ASP.NET MembershipProvider/RoleProvider in self-hosted WCF services?是否可以在自托管 WCF 服务中使用 ASP.NET MembershipProvider/RoleProvider?
【发布时间】:2009-08-21 12:29:54
【问题描述】:

我正在尝试使用自定义 ASP.NET MembershipProvider 和 RoleProvider 来处理我的服务的安全性。该服务自托管在控制台应用程序中,而不是在 IIS 中。 我使用带有基本身份验证的 webHttpBinding。我将 serviceCredentials 和 serviceAuthorization 配置为使用提供程序。提供者真的被初始化了。但是 WCF 似乎忽略了我的设置并尝试将用户登录到 Windows。我从事件日志中发现了这一点,并通过将我的 Windows 凭据发送到服务来证明这一点。下面你可以看到我的配置和调试截图。为什么使用 windows 进行身份验证?也许没有 IIS 就无法使用 ASP.NET 身份验证提供程序?

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

  <system.web>
    <roleManager
    enabled="true"
    defaultProvider="CustomRoleProvider">
      <providers>
        <clear/>
        <add
            name="CustomRoleProvider"
            type="CustomRoles.CustomRoleProvider, CustomRoles"/>
      </providers>
    </roleManager>
    <membership defaultProvider="CustomMembershipProvider" userIsOnlineTimeWindow="15">
      <providers>
        <clear/>
        <add name="CustomMembershipProvider"
          type="CustomRoles.CustomMembershipProvider, CustomRoles"/>
      </providers>
    </membership>
  </system.web>
  <system.serviceModel>
    <bindings>
      <webHttpBinding>
        <binding name="webHttp">
          <security mode="TransportCredentialOnly">
            <transport clientCredentialType="Basic" />
          </security>
        </binding>
      </webHttpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior name="Service">
          <serviceAuthorization principalPermissionMode="UseAspNetRoles"
            roleProviderName="CustomRoleProvider" />
          <serviceCredentials>
            <userNameAuthentication userNamePasswordValidationMode="MembershipProvider"
              membershipProviderName="CustomMembershipProvider" />
          </serviceCredentials>
          <serviceSecurityAudit auditLogLocation="Application" serviceAuthorizationAuditLevel="SuccessOrFailure"
            messageAuthenticationAuditLevel="SuccessOrFailure" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <services>
      <service behaviorConfiguration="Service" name="CustomRoles.Service">
        <endpoint address="http://127.0.0.1:8060" binding="webHttpBinding"
          bindingConfiguration="webHttp" contract="CustomRoles.IService" />
      </service>
    </services>
  </system.serviceModel>
</configuration>

这就是我在调试时看到的。为什么要使用 windows 进行身份验证?

credentials screen http://img81.imageshack.us/img81/1289/credentials.gif

link to full size screen

【问题讨论】:

  • 使用应用程序发现角色提供者正在工作,但成员资格提供者没有。目前,我正在检查它是否由于 asp.net 和自托管服务实例的初始化方式不同而被忽略。但这似乎真的很奇怪。现在我将尝试总结问题。用户名验证有 3 个选项 - windows、membershipprovider 和 custom。自定义工作,windows 工作,但成员选项被忽略,wcf 使用 windows 代替它。为什么?

标签: wcf authentication asp.net-membership roleprovider webhttpbinding


【解决方案1】:

我正在尝试做同样的事情。

我的服务运行良好,我可以通过服务跟踪查看器跟踪对服务的调用。

剩下的唯一问题是我没有收到任何对电话的答复。我的应用程序正在冻结,并且我在通话中遇到了 TimoutException。这是我的设置:

<system.web>
    <membership defaultProvider="ClientAuthenticationMembershipProvider">
      <providers>
        <add name="ClientAuthenticationMembershipProvider"
             type="System.Web.ClientServices.Providers.ClientFormsAuthenticationMembershipProvider, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
             serviceUri="http://localhost:21200/Authentication_JSON_AppService.axd"
             credentialsProvider="LacT.Windows.LoginWindow, LacT.Windows" />

        <add name="FooMembershipProvider"
             type="Foo.Security.Business.Provider.FooTMembershipProvider, LacT.Security.Business"
             serviceUri="http://localhost:21200/Authentication_JSON_AppService.axd"
             credentialsProvider="Foo.Windows.LoginWindow, Foo.Windows" />
      </providers>
    </membership>
    <roleManager defaultProvider="ClientRoleProvider" enabled="true">
      <providers>
        <add name="ClientRoleProvider"
             type="System.Web.ClientServices.Providers.ClientRoleProvider, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
             serviceUri="http://localhost:21200/Role_JSON_AppService.axd"
             cacheTimeout="86400" />
      </providers>
    </roleManager>
  </system.web>

还有服务模式……`

<behaviors>
  <endpointBehaviors>
    <behavior name="WebBehavior">
      <webHttp />
      <enableWebScript />
    </behavior>
  </endpointBehaviors>
  <serviceBehaviors>
    <behavior name="WebBehavior">
      <serviceMetadata httpGetEnabled="true" httpGetUrl="" />
      <serviceDebug includeExceptionDetailInFaults="true" />
    </behavior>
  </serviceBehaviors>
</behaviors>


<bindings>
  <basicHttpBinding>
    <binding name="basicHttpMode">
      <security mode="None" />
    </binding>
  </basicHttpBinding>
  <webHttpBinding>
    <binding name="webHttpMode">
      <security mode="None" />
    </binding>
  </webHttpBinding>
</bindings>

<services>
  <service behaviorConfiguration="WebBehavior"
           name="Foo.Security.Business.Manager.Wcf.Host.SecurityManager">

    <endpoint address=""
              binding="webHttpBinding"
              contract="Foo.Security.Business.Contract.ISecurityContract"
              behaviorConfiguration="WebBehavior"
              bindingConfiguration="webHttpMode" />
    <host>
      <baseAddresses>
        <add baseAddress="http://localhost:21200" />
      </baseAddresses>
    </host>
  </service>
</services>

`

也许通过这段代码,它可以帮助您弄清楚您的代码发生了什么。 如果你找到了,请告诉我。

【讨论】:

    【解决方案2】:

    我在 WCF 大师班期间做过这个,所以这绝对是可能的。不幸的是,我没有在实践中使用它,现在已经是一年前了......

    但是,请尝试this link,并查找有关 ASP.NET 成员资格的不同下载。这基本上是培训课程的成果。

    【讨论】:

      【解决方案3】:

      可以:

      <?xml version="1.0"?>
      <configuration>
         <startup>
            <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
         </startup>
         <connectionStrings>
            <add name="mySqlConnection" connectionString="Data Source=.\SQLEXPRESS2012;Integrated Security=SSPI;Initial Catalog=aspnetdb;"/>
         </connectionStrings>
         <system.web>
            <compilation debug="true"/>
            <!-- Configure the Sql Membership Provider -->
            <membership defaultProvider="MySqlMembershipProvider" userIsOnlineTimeWindow="15">
               <providers>
                  <clear/>
                  <add name="MySqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="mySqlConnection" applicationName="UsersManagementNavigationApplication" enablePasswordRetrieval="false" enablePasswordReset="false" requiresQuestionAndAnswer="false" requiresUniqueEmail="true" passwordFormat="Hashed"/>
               </providers>
            </membership>
      
            <!-- Configure the Sql Role Provider -->
            <roleManager enabled="true" defaultProvider="MySqlRoleProvider">
               <providers>
                  <clear/>
                  <add name="MySqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="mySqlConnection" applicationName="UsersManagementNavigationApplication"/>
               </providers>
            </roleManager>
         </system.web>
         <system.serviceModel>
            <bindings>
               <webHttpBinding>
                  <binding name="webBinding">
                     <security mode="TransportCredentialOnly">
                        <transport clientCredentialType="Basic"/>
                     </security>
                  </binding>
               </webHttpBinding>
               <basicHttpBinding>
                  <binding name="basicBindingConfiguration">
                     <security mode="TransportCredentialOnly">
                        <transport clientCredentialType="Basic"/>
                     </security>
                  </binding>
               </basicHttpBinding>
            </bindings>
            <behaviors>
               <endpointBehaviors>
                  <behavior name="webEndpointBehavior">
                     <webHttp/>
                  </behavior>
               </endpointBehaviors>
               <serviceBehaviors>
                  <behavior name="webServiceBehavior">
                     <serviceMetadata httpGetEnabled="true"/>
                     <serviceThrottling/>
                     <serviceDebug/>
                  </behavior>
                  <behavior name="myServiceBehavior">
                     <!-- Configure role based authorization to use the Role Provider -->
                     <serviceAuthorization principalPermissionMode="UseAspNetRoles" roleProviderName="MySqlRoleProvider">
                     </serviceAuthorization>
                     <serviceCredentials>
                        <!-- Configure user name authentication to use the Membership Provider -->
                        <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="WcfServiceHTTPSelfHosted.MyCustomValidator, WcfServiceHTTPSelfHosted"/>
                     </serviceCredentials>
                     <!-- To avoid disclosing metadata information, set the value below to false before deployment -->
                     <serviceMetadata httpGetEnabled="true"/>
                     <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
                     <serviceDebug includeExceptionDetailInFaults="false"/>
                  </behavior>
               </serviceBehaviors>
            </behaviors>
            <services>
               <service behaviorConfiguration="myServiceBehavior" name="WcfServiceHTTPSelfHosted.WcfServiceHTTPSelfHosted">
                  <endpoint address="" binding="basicHttpBinding" bindingConfiguration="basicBindingConfiguration"
                     contract="WcfServiceHTTPSelfHosted.IWcfServiceHTTPSelfHosted" />
                  <endpoint address="web" behaviorConfiguration="webEndpointBehavior"
                     binding="webHttpBinding" bindingConfiguration="webBinding"
                     contract="WcfServiceHTTPSelfHosted.IWcfServiceHTTPSelfHosted" />
                  <endpoint address="mex" binding="mexHttpBinding" bindingConfiguration=""
                     contract="IMetadataExchange" />
                  <host>
                     <baseAddresses>
                        <add baseAddress="http://localhost:50002/WcfServiceHTTPSelfHosted/" />
                     </baseAddresses>
                  </host>
               </service>
            </services>
         </system.serviceModel>
      </configuration>
      

      并使用自定义的 UserNamePasswordValidator:

      public class MyCustomValidator : UserNamePasswordValidator
         {
      
            public MyCustomValidator()
            {
      
            }
      
            public override void Validate(string userName, string password)
            {
               if (!Membership.ValidateUser(userName, password))
               {
                  throw new SecurityTokenException("Users validation failed: " + userName);
               }
            }
         }
      

      这很好用!

      【讨论】:

      • 如果您愿意,可以应用 SSL 安全模式
      猜你喜欢
      • 2019-08-29
      • 2011-02-24
      • 1970-01-01
      • 2012-04-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-13
      • 1970-01-01
      相关资源
      最近更新 更多