ASP.NET 成员资格提供程序身份验证无法对 WCF 服务进行身份验证

发布于 2024-09-29 12:24:58 字数 4207 浏览 3 评论 0 原文

我有一个启用了角色的 SqlMembershipProvider 存储。此配置已配置,用户“devtest”的角色为“xxUser”和“xxAdmin”。

我还有一个 WCF 服务,我想对其进行身份验证和授权。我的问题是:

  1. 没有授权 发生了,代码就执行了 尽管有策略属性,
  2. 我没有获得任何身份或安全性 上下文所以不知道是谁 调用我需要的服务

  1. 知道哪个用户正在调用 方法
  2. 某种程度拒绝的 如果权限不匹配的用户 (理想情况下应该执行 内 角色提供者/成员提供者/WCF 但如果必须的话可以自己做)
  3. 传输中的 SSL

我的服务合同设置如下:

    [ServiceContract]
    public interface ISupportService
    {
        [OperationContract]
        [PrincipalPermission(SecurityAction.Demand, Role = "ThisRoleDoesNotExist")]
        List<BaseInterestRate> GetAllBaseInterestRates();
    }

代码足够简单:

public class SupportService : ISupportService
{
    public List<BaseInterestRate> GetAllBaseInterestRates()
    {
        OperationContext operationContext = OperationContext.Current;
        ServiceSecurityContext serviceSecurityContext = ServiceSecurityContext.Current; // is always null

        using (xxxEntities entities = new xxxEntities())
        {
            return new List<BaseInterestRate>(entities.BaseInterestRates);
        }
    }}

我的服务配置如下:

-->

<behaviors>
  <serviceBehaviors>
      <behavior name="SupportServiceBehavior">
          <serviceMetadata httpGetEnabled="false" httpsGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false" />
          <serviceAuthorization principalPermissionMode="UseAspNetRoles" roleProviderName="AspNetSqlRoleProvider" />
          <serviceCredentials>
              <userNameAuthentication userNamePasswordValidationMode="MembershipProvider" 
 membershipProviderName="SqlMembershipProvider" />
          </serviceCredentials>
      </behavior>
    <behavior>     
      <serviceMetadata httpGetEnabled="true"/>
      <serviceDebug includeExceptionDetailInFaults="false"/>
    </behavior>
  </serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />

已经配置了 MembershipProvider:

  <membership defaultProvider="SqlMembershipProvider" >
      <providers>
          <clear/>
          <add name="SqlMembershipProvider"
   connectionStringName="SqlMembershipProvider"
   applicationName="xxx"
   type="System.Web.Security.SqlMembershipProvider" />
      </providers>
  </membership>
  <roleManager enabled="true">
      <providers>
          <clear />
          <add connectionStringName="SqlMembershipProvider" applicationName="xxx"
           name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" />
          <add applicationName="xxx" name="AspNetWindowsTokenRoleProvider"
           type="System.Web.Security.WindowsTokenRoleProvider" />
      </providers>
  </roleManager>

我已按照这些页面上的说明进行操作:

我至少预计会出现证书/传输/等问题。因异常而失败,但我可以直接在 WCF 调用中进行调试。我没有可用的安全上下文/用户上下文,当我使用不属于上述两个角色的用户时(我在上面的代码示例中这样做),我不会被“踢出”。

我的客户端应用程序当前是一个 Web 应用程序,但最终还将提供 Windows 窗体应用程序和测试套件。我当前正在使用 ASP.NET WebDev 服务器并运行 .NET 4.0。

我错过了什么吗?

I have a SqlMembershipProvider store with Roles enabled. This is configured and has the user "devtest" in the roles "xxUser" and "xxAdmin".

I also have a WCF service, which I want to authenticate and authorize against. My problem is that:

  1. the authorisation is not
    happening, code just executes
    despite the policy attribute
  2. I don't get any identity or security
    context so do not know who is
    calling the service

I need:

  1. to know which user is calling the
    method
  2. some degree of rejecting
    users if permissions don't match up
    (ideally this should be performed
    within the
    RoleProvider/MembershipProvider/WCF
    but can do it myself if I have to)
  3. SSL in transport

I have my service contract set up thus:

    [ServiceContract]
    public interface ISupportService
    {
        [OperationContract]
        [PrincipalPermission(SecurityAction.Demand, Role = "ThisRoleDoesNotExist")]
        List<BaseInterestRate> GetAllBaseInterestRates();
    }

the code is simple enough:

public class SupportService : ISupportService
{
    public List<BaseInterestRate> GetAllBaseInterestRates()
    {
        OperationContext operationContext = OperationContext.Current;
        ServiceSecurityContext serviceSecurityContext = ServiceSecurityContext.Current; // is always null

        using (xxxEntities entities = new xxxEntities())
        {
            return new List<BaseInterestRate>(entities.BaseInterestRates);
        }
    }}

My service configuration is thus:

-->

<behaviors>
  <serviceBehaviors>
      <behavior name="SupportServiceBehavior">
          <serviceMetadata httpGetEnabled="false" httpsGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false" />
          <serviceAuthorization principalPermissionMode="UseAspNetRoles" roleProviderName="AspNetSqlRoleProvider" />
          <serviceCredentials>
              <userNameAuthentication userNamePasswordValidationMode="MembershipProvider" 
 membershipProviderName="SqlMembershipProvider" />
          </serviceCredentials>
      </behavior>
    <behavior>     
      <serviceMetadata httpGetEnabled="true"/>
      <serviceDebug includeExceptionDetailInFaults="false"/>
    </behavior>
  </serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />

Having already configured the MembershipProvider:

  <membership defaultProvider="SqlMembershipProvider" >
      <providers>
          <clear/>
          <add name="SqlMembershipProvider"
   connectionStringName="SqlMembershipProvider"
   applicationName="xxx"
   type="System.Web.Security.SqlMembershipProvider" />
      </providers>
  </membership>
  <roleManager enabled="true">
      <providers>
          <clear />
          <add connectionStringName="SqlMembershipProvider" applicationName="xxx"
           name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" />
          <add applicationName="xxx" name="AspNetWindowsTokenRoleProvider"
           type="System.Web.Security.WindowsTokenRoleProvider" />
      </providers>
  </roleManager>

I have followed the instructions at these pages to the letter:

I would at lest expect an issue with certificates/transport/etc. to fail with exceptions, but I can debug right in and over the WCF call. I have no security context/ user context available to me and when I use a user not in the two mentioned roles (which I do in the code example above), I don't get "kicked out".

My client app is currently a Web App, but will ultimately also serve a Windows Forms app and Test suite. I'm currently using the ASP.NET WebDev server and am running .NET 4.0.

Am I missing something?

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

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

发布评论

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

评论(3

罪歌 2024-10-06 12:24:58

我对 WCF Rest 服务有点陌生,但在我自己的测试过程中,我遇到了与此类似的问题。我看到了这个视频,它有点帮助(即使它不完全是我想要做的):

http://channel9.msdn.com/blogs/rojacobs/endpointtv-secure-restful-services-with-aspnet-membership

本质上问题是在 asp.net 配置下,我必须禁用匿名访问才能使用 MembershipProvider 身份验证:

system.web>
    <authorization>
      <deny users="?" />
    </authorization>
...

I'm a little new to WCF Rest services, but during my own testing I ran into a similar problem to this. I came across this video, which helped a bit (even if it wasn't quite what I was trying to do):

http://channel9.msdn.com/blogs/rojacobs/endpointtv-securing-restful-services-with-aspnet-membership

Essentially the problem was that under the asp.net configuration I had to disable anonymous access in order for it to use the MembershipProvider authentication:

system.web>
    <authorization>
      <deny users="?" />
    </authorization>
...
川水往事 2024-10-06 12:24:58

我认为您不能在界面上设置主体权限。
我敢打赌,如果你将它移到服务实现方法上,它会起作用

,或者至少会因为不同的原因而开始中断(我目前陷入了这一点 - 我遇到了访问被拒绝的异常 - 希望你不会!)

(我首先尝试将它们也在合约界面上)

I don't think you can set the principal permission on the interface.
I bet if you move it onto the service implementation method it will work

or at least start breaking for a different reason (I am currently stuck at that point - I get access denied exceptions - hopefully you dont!)

(I first tried to put them on the contract interface also)

走走停停 2024-10-06 12:24:58

这是使用 SSL 自托管的 wcf 服务的正确配置:

<?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="Transport">
                  <transport clientCredentialType="Basic"/>
               </security>
            </binding>
         </webHttpBinding>
         <basicHttpBinding>
            <binding name="basicBindingConfiguration">
               <security mode="Transport">
                  <transport clientCredentialType="Basic"/>
               </security>
            </binding>
         </basicHttpBinding>
      </bindings>
      <behaviors>
         <endpointBehaviors>
            <behavior name="webEndpointBehavior">
               <webHttp/>
            </behavior>
         </endpointBehaviors>
         <serviceBehaviors>
            <behavior name="webServiceBehavior">
               <serviceMetadata httpsGetEnabled="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="WcfServiceHTTPSSelfHosted.MyCustomValidator, WcfServiceHTTPSSelfHosted"   />
               </serviceCredentials>
               <!-- To avoid disclosing metadata information, set the value below to false before deployment -->
               <serviceMetadata httpsGetEnabled="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="WcfServiceHTTPSSelfHosted.WcfServiceHTTPSSelfHosted">
            <endpoint address="" binding="basicHttpBinding" bindingConfiguration="basicBindingConfiguration" contract="WcfServiceHTTPSSelfHosted.IWcfServiceHTTPSSelfHosted"/>
            <endpoint address="web" behaviorConfiguration="webEndpointBehavior" binding="webHttpBinding" bindingConfiguration="webBinding" contract="WcfServiceHTTPSSelfHosted.IWcfServiceHTTPSSelfHosted"/>
            <endpoint address="mex" binding="mexHttpsBinding" bindingConfiguration="" contract="IMetadataExchange"/>
            <host>
               <baseAddresses>
                  <add baseAddress="https://localhost:50001/WcfServiceHTTPSSelfHosted/"/>
               </baseAddresses>
            </host>
         </service>
      </services>
   </system.serviceModel>
</configuration>

如果您想了解更多信息,请查看以下内容:

http://www.albertoschiassi.it/Home/tabid/55/EntryId/94/Use-ASP-NET -SqlMemberShipProvider-in-WCF-self-hosted-service.aspx

http://www.albertoschiassi.it/Home/tabid/55/EntryId/95/Use-ASP-NET- SqlMemberShipProvider-in-WCF-self-hosted-service-with-SSL.aspx

this is the correct configuration for wcf service self-hosted with SSL:

<?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="Transport">
                  <transport clientCredentialType="Basic"/>
               </security>
            </binding>
         </webHttpBinding>
         <basicHttpBinding>
            <binding name="basicBindingConfiguration">
               <security mode="Transport">
                  <transport clientCredentialType="Basic"/>
               </security>
            </binding>
         </basicHttpBinding>
      </bindings>
      <behaviors>
         <endpointBehaviors>
            <behavior name="webEndpointBehavior">
               <webHttp/>
            </behavior>
         </endpointBehaviors>
         <serviceBehaviors>
            <behavior name="webServiceBehavior">
               <serviceMetadata httpsGetEnabled="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="WcfServiceHTTPSSelfHosted.MyCustomValidator, WcfServiceHTTPSSelfHosted"   />
               </serviceCredentials>
               <!-- To avoid disclosing metadata information, set the value below to false before deployment -->
               <serviceMetadata httpsGetEnabled="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="WcfServiceHTTPSSelfHosted.WcfServiceHTTPSSelfHosted">
            <endpoint address="" binding="basicHttpBinding" bindingConfiguration="basicBindingConfiguration" contract="WcfServiceHTTPSSelfHosted.IWcfServiceHTTPSSelfHosted"/>
            <endpoint address="web" behaviorConfiguration="webEndpointBehavior" binding="webHttpBinding" bindingConfiguration="webBinding" contract="WcfServiceHTTPSSelfHosted.IWcfServiceHTTPSSelfHosted"/>
            <endpoint address="mex" binding="mexHttpsBinding" bindingConfiguration="" contract="IMetadataExchange"/>
            <host>
               <baseAddresses>
                  <add baseAddress="https://localhost:50001/WcfServiceHTTPSSelfHosted/"/>
               </baseAddresses>
            </host>
         </service>
      </services>
   </system.serviceModel>
</configuration>

if you want more info take a look this:

http://www.albertoschiassi.it/Home/tabid/55/EntryId/94/Use-ASP-NET-SqlMemberShipProvider-in-WCF-self-hosted-service.aspx

and

http://www.albertoschiassi.it/Home/tabid/55/EntryId/95/Use-ASP-NET-SqlMemberShipProvider-in-WCF-self-hosted-service-with-SSL.aspx

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