WCF:使用PrincipalPermissions自定义RoleProvider:似乎没有被命中/如何调试它?

时间:2012-06-29 11:49:33

标签: wcf authorization roleprovider principalpermission

我有一个继承RoleProvider的自定义角色提供程序。在网络应用程序中,这没有问题。

但是我也在WCF服务中使用它,并且在进入它时遇到了很大的问题。在某种程度上,我怀疑它根本没有被击中。如果我依次打开任何主要权限,我会拒绝访问,并且堆栈跟踪完全没有用。甚至WCF的痕迹也确实有助于确定发生了什么。

我知道TennisRoleProvider使用其默认构造函数并通过测试验证了其方法。这似乎是一个整合问题。

所以片段......

编辑:我已经将角色提供程序移动到服务程序集中,因为需要涉及需要涉及GAK和密钥(需要完全信任地运行)。我走了那条路,但事情仍然没有奏效,所以决定简单地将东西转移到服务项目中以简化。仍然没有快乐。

<roleManager defaultProvider="TennisRoleProvider"
             enabled="true"
             >
  <providers>
    <clear/>
    <add name="TennisRoleProvider"
         type="Tennis.Security.TennisRoleProvider, Tennis.Security" />
  </providers>
</roleManager>

   <bindings>
     <wsHttpBinding>
        <binding name="wsHttpUserName">
          <security mode="TransportWithMessageCredential">
            <message clientCredentialType="UserName"/>
            <transport clientCredentialType="None"/>
          </security>
        </binding>
     </wsHttpBinding>
   <bindings/>


    <behavior name="RoleBehavior">
       <serviceCredentials>
         <serviceCertificate findValue="john-pc"
                      storeLocation="LocalMachine"
                      storeName="My"
                      x509FindType="FindBySubjectName"/>
       <userNameAuthentication userNamePasswordValidationMode="Custom" 
customUserNamePasswordValidatorType="Tennis.Components.TennisUserValidator, Tennis.Components"/>
      </serviceCredentials>

      <serviceAuthorization principalPermissionMode="UseAspNetRoles" 
                            roleProviderName="TennisRoleProvider">
      </serviceAuthorization>

      <serviceMetadata httpsGetEnabled="true"/>
      <serviceDebug includeExceptionDetailInFaults="true"/>
      <errorHandler />
    </behavior>

   <services>
      <service name="Tennis.Service.Services"
               behaviorConfiguration="RoleBehavior">
          <endpoint address="Family"
                 binding="wsHttpBinding"
                 bindingConfiguration="wsHttpUserName"
                 contract="Tennis.Service.Contracts.IFamilyAdmin"
                  />
      </service>
    </services>

然后在服务方法上我有以下(Roles.Family admin是一个字符串)

[PrincipalPermission(SecurityAction.Demand, Name = Roles.FamilyAdmin)]
public VoidResult<SuccessEnum> UpdateFamily(Family family)
{

}

所以有2个问题...... 1)我做错了什么? 2)我如何进入WCF以确切地知道出了什么问题?

干杯

日志中错误的堆栈跟踪如下所示 请注意,与我上面使用的权限不同(Namley'授权'而不是'FamilyAdmin'。但实际上这些值匹配且用户具有正确的权限。

<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent">
<System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system">
<EventID>131076</EventID>
<Type>3</Type>
<SubType Name="Warning">0</SubType>
<Level>4</Level>
<TimeCreated SystemTime="2012-06-29T12:45:30.2469191Z" />
<Source Name="System.ServiceModel" />
<Correlation ActivityID="{6e59b4f4-d59b-42eb-ad8e-4d5853f72900}" />
<Execution ProcessName="w3wp" ProcessID="9388" ThreadID="18" />
<Channel />
<Computer>JOHNN-PC</Computer>
</System>
<ApplicationData>
<TraceData>
<DataItem>
<TraceRecord xmlns="http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord" Severity="Warning">
<TraceIdentifier>http://msdn.microsoft.com/en-GB/library/System.ServiceModel.Diagnostics.TraceHandledException.aspx</TraceIdentifier>
<Description>Handling an exception.</Description>
<AppDomain>/LM/W3SVC/2/ROOT/Tennis-1-129854474506679191</AppDomain>
<Exception>
<ExceptionType>System.Security.SecurityException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType>
<Message>Request for principal permission failed.</Message>
<StackTrace>
at System.Security.Permissions.PrincipalPermission.ThrowSecurityException()
at System.Security.Permissions.PrincipalPermission.Demand()
at System.Security.PermissionSet.DemandNonCAS()
at Nomical.Tennis.Service.Services.GetBookingsForUser(DateTime start, DateTime end) in c:\tfs\Tennis\TennisSolution\TennisCourts\Services.svc.cs:line 388
at SyncInvokeGetBookingsForUser(Object , Object[] , Object[] )
at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]&amp; outputs)
</StackTrace>
<ExceptionString>System.Security.SecurityException: Request for principal permission failed.
   at System.Security.Permissions.PrincipalPermission.ThrowSecurityException()
   at System.Security.Permissions.PrincipalPermission.Demand()
   at System.Security.PermissionSet.DemandNonCAS()
   at Tennis.Service.Services.GetBookingsForUser(DateTime start, DateTime end) in c:\tfs\Tennis\TennisSolution\TennisCourts\Services.svc.cs:line 388
   at SyncInvokeGetBookingsForUser(Object , Object[] , Object[] )
   at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]&amp; outputs)
The action that failed was:
Demand
The type of the first permission that failed was:
System.Security.Permissions.PrincipalPermission
The first permission that failed was:
&lt;IPermission class="System.Security.Permissions.PrincipalPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
version="1"&gt;
&lt;Identity Authenticated="true"
ID="Authorised"/&gt;
&lt;/IPermission&gt;

The demand was for:
&lt;IPermission class="System.Security.Permissions.PrincipalPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
version="1"&gt;
&lt;Identity Authenticated="true"
ID="Authorised"/&gt;
&lt;/IPermission&gt;

The assembly or AppDomain that failed was:
mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionString>
</Exception>
</TraceRecord>
</DataItem>
</TraceData>
</ApplicationData>
</E2ETraceEvent>

编辑:基于下面的答案,我在构造函数中添加了几行代码 - 虽然它们没有实现任何东西,但却鼓励我查询线程静态类。

编辑:给出一个关于日志更新日志的问题,以显示它确实来自日志 - 或者我很困惑;)

TennisRoleProvider在非公开成员中引用它 - 而且当我覆盖Name以使其返回时我会认识到它是由它返回的。

2 个答案:

答案 0 :(得分:1)

问题是我在程序集/应用程序域中使用安全性。

我需要让所有东西都值得信任并签名才能发挥作用。

答案 1 :(得分:0)

在您的某个角色提供程序中添加一个断点。如果您的WCF服务是自托管的,请启动主机,或者如果您在IIS下拥有它,只需访问其* svc文件即可。从visual studio转到Debug,单击Attach to Process并从列表w3wp.exe中选择您的工作进程(如果您无法看到它,请选中两个复选框“显示所有用户的进程”和“显示所有进程”)现在你可以附加到你的WCF服务执行过程。最后要做的事情,从你的客户端调用你的服务的一个测试方法,看看你的断点是否受到打击。

如果这不起作用,则只需在服务级别启用跟踪,并检查跟踪日志文件中是否有任何可疑信息。