是否可以在自托管 WCF 服务中使用 ASP.NET MembershipProvider/RoleProvider?

发布于 2024-08-02 17:20:50 字数 2842 浏览 7 评论 0 原文

我正在尝试使用自定义 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 进行身份验证?

凭证屏幕 http://img81.imageshack.us/img81/1289/credentials.gif< /a>

链接到全尺寸屏幕

I am trying to use custom ASP.NET MembershipProvider and RoleProvider to handle security for my service. The service is self-hosted in a console app, not in IIS.
I use webHttpBinding with Basic Authentication. I configured serviceCredentials and serviceAuthorization to use providers. Providers really get initialized. But WCF seems to ignore my settings and tryes to login user to Windows. I figured that out from Events Log, and proved by sending my windows credentials to the service. Below you can see my configuration and debug screenshots. Why is it using windows for auth? Maybe it is impossible to use ASP.NET auth providers without IIS?

<?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>

That's what I see when debug. Why is it using windows for auth?

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

link to full size screen

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

梦行七里 2024-08-09 17:20:50

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

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

剩下的唯一问题是我没有收到任何电话回复。我的应用程序冻结,并且调用时出现 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>

`

也许通过这段代码,它可以帮助您弄清楚您的代码发生了什么。
如果你发现让我知道一些事情。

I'm trying to do the same thing.

My service is working well, I'm able to trace the call made to the service via the Service Trace Viewer.

The only problem remaining is that I don't receive any answer to the call. My application is freezing and I have a TimoutException on the call. Here's my settings :

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

And the service model...`

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

`

Maybe with this piece of code it can help you to figure out what's going on with yours.
If you find let me know something.

优雅的叶子 2024-08-09 17:20:50

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

但是,请尝试 此链接,并查找有关 ASP.NET 会员资格内容的不同下载。这基本上就是培训课程的结果。

I've done this during the WCF Master Class, so it is definitely possible. Unfortunately I did not use this in practice and it's a year ago now...

However, try this link, and look for the different downloads about ASP.NET membership stuff. It is basically the outcome of the training session.

蓝眼睛不忧郁 2024-08-09 17:20:50

是的,是可能的:

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

这工作正常!

Yes is possible:

<?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>

And uses a custom 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);
         }
      }
   }

this works fine!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文