После посещения курсов и блогов Доминика Байера Pluralsight, посвященных WIF 4.5, я все еще не могу решить проблему. Я использую службы данных WCF с авторизацией на основе утверждений с использованием WIF 4.5.
Мои ClaimsAuthenticationManager
и ClaimsAuthorizationManager
настроены в файле web.config:
<section name="system.identityModel" type="System.IdentityModel.Configuration.SystemIdentityModelSection, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
...
<system.identityModel>
<identityConfiguration>
<claimsAuthenticationManager type="Magnum.WCFDataService.ClaimsTransformer, Magnum.WCFDataService" />
<claimsAuthorizationManager type="Magnum.WCFDataService.AuthorizationManager, Magnum.WCFDataService" />
</identityConfiguration>
</system.identityModel>
Вот содержимое моего AuthorizationManager:
public class AuthorizationManager : ClaimsAuthorizationManager
{
public override bool CheckAccess(AuthorizationContext context)
{
var action = context.Action.First();
if (action.Type.Equals(ClaimPermission.ActionType))
{
var resource = context.Resource.First();
return context.Principal.HasClaim(resource.Value, action.Value);
}
return base.CheckAccess(context);
}
}
Первая проблема, с которой я столкнулся, заключалась в том, что WCF автоматически вызывал мой AuthorizationManager
для каждого запроса и передавал глагол http для действия и URL-адрес ресурса, это было бесполезно, поскольку я хотел вручную определить, когда утверждения были вызваны с помощью запроса и перехватчики изменений, предоставляемые службами данных. Здесь я нашел объяснение Доминика. проблемы, предлагающей написать собственный класс и атрибут для замены ClaimsPrincipalPermission
. Все прошло нормально, атрибут находится в перехватчике изменений и запросов и вызывает мой AuthorizationManager
во второй раз с моим пользовательским URI.
Теперь проблема в том, что для GET-запросов он работает без сучка и задоринки. AuthorizationManager
один раз вызывается WCF, который я игнорирую, и второй раз, используя мой атрибут, который я обрабатываю. Однако для запросов POST (в любое время, когда у меня есть перехватчик изменений), когда AuthorizationManager
вызывается во второй раз с моим URI, принципал в контексте представляет собой GenericPrincipal
, а не ClaimsPrincipal
, и не содержит моих утверждений для проверки.
Как я могу гарантировать, что я всегда получаю свой ClaimsPrincipal
, который генерируется из моего ClaimsTransformer (ClaimsAuthenticationManager) каждый раз, когда вызывается AuthorizationManager
?
Дополнительная информация После некоторого интенсивного поиска в Google я сузил проблему. Я вижу GenericPrincipal только в том случае, если я использую SaveChangesOptions.Batch при вызове метода SaveChanges из моего клиента. Если я не отправлю пакетное обновление, я получу ClaimsPrincipal как обычно. Итак, новый вопрос; Как сохранить ClaimsPrincipal для пакетных обновлений?
Я нашел некоторую информацию в ветке MSDN (http://social.msdn.microsoft.com/Forums/en-US/35eb817d-363c-4a94-b9eb-351cd0d8567f/batch-update-and-impersonation-текущийпользователь), заявив, что мне нужно использовать в моем web.config следующее:
<serviceAuthorization principalPermissionMode="Always" impersonateCallerForAllOperations="true" impersonateOnSerializingReply="true" />
но теперь я получаю следующую ошибку:
The service operation 'ProcessRequestForMessage' that belongs to the contract with the 'IRequestHandler' name and the 'http://tempuri.org/' namespace does not allow impersonation.