WCF: Custom RoleProvider с PrincipalPermissions: похоже, не попадает / как его отлаживать?

У меня есть собственный поставщик ролей, который наследуется от 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, чтобы он возвращал что-то, что я узнаю, это было возвращено им.


person John Nicholas    schedule 29.06.2012    source источник
comment
Использовали ли вы настроенную трассировку WCF и средство просмотра служебной трассировки (msdn.microsoft. com/en-us/library/ms732023.aspx) ? Это обычно дает ценную информацию.   -  person Simon Mourier    schedule 03.07.2012
comment
да, вот откуда подробная ошибка выше. Я не получаю ничего полезного из непосредственного исключения в wcf. Они необходимы :D   -  person John Nicholas    schedule 03.07.2012
comment
Это может быть ничем, но я заметил, что в вашем web.config под behavior -> serviceCredentials -> serviceCertificate findValue="john-pc", но трассировка стека сообщает <Computer>JOHNN-PC</Computer>. Может ли это быть ошибкой сертификата из-за несоответствия имени компьютера?   -  person Infotekka    schedule 06.07.2012
comment
Привет, да, это результат моей очистки данных ;) с сертификатами все в порядке - хотя я должен признать, что для настройки ЦС потребовалось некоторое время.   -  person John Nicholas    schedule 06.07.2012
comment
Я подозреваю, что это связано с подписанием, поскольку я пытаюсь использовать безопасность через границы сборки.   -  person John Nicholas    schedule 12.09.2012


Ответы (2)


Проблема заключалась в том, что я использую безопасность в сборках/доменах приложений.

Мне нужно сделать все доверенным и подписанным, чтобы это работало.

person John Nicholas    schedule 08.10.2012

Поставьте точку останова в одном из ваших поставщиков ролей. Если ваша служба WCF размещена самостоятельно, запустите хост или, если он у вас есть в IIS, просто получите доступ к его файлу * svc. Из Visual Studio перейдите в Debug, нажмите «Присоединить к процессу» и выберите свой рабочий процесс из списка w3wp.exe (если вы не видите его, установите оба флажка «Показать процессы от всех пользователей» и «Показать процессы во всех сеансы». Теперь вы можете подключиться к процессу выполнения службы WCF. Последнее, что нужно сделать, из вашего клиента просто вызвать один из тестовых методов вашей службы и посмотреть, сработает ли ваша точка останова.

Если это не сработает, просто включите трассировку на уровне службы и проверьте файлы журнала трассировки на наличие подозрительной информации.

person Mihai H    schedule 29.06.2012
comment
о, лол ... не подумал подключиться к процессу :/ ... последний фрагмент кода в моем вопросе - это все, что я могу почерпнуть из файлов журнала. - person John Nicholas; 29.06.2012
comment
ну, у меня есть и я не могу поразить точки останова, я боюсь. Как только я вызываю метод службы, он завершается с ошибкой PrincipalPermission (и мне действительно кажется, что либо мой код работает на чем-то (контекст/поток), я не могу отладить, либо он вообще не срабатывает) - person John Nicholas; 29.06.2012
comment
хорошая идея, к сожалению, эта ссылка не имеет значения. Все еще не могу попасть в точку останова в поставщике ролей... я могу нажать ее в конструкторе... тогда он сразу же говорит, что разрешение отклонено - person John Nicholas; 29.06.2012
comment
Что ж, шансы помочь вам очень малы, так как у меня нет доступа к вашему проекту. - person Mihai H; 29.06.2012