在关注 Dominick Baier 的 Pluralsight 课程和围绕 WIF 4.5 的博客之后,我仍然遇到无法解决的问题。我正在使用 WCF 数据服务和使用 WIF 4.5 的基于声明的授权。
我在 web.config 中设置了我的ClaimsAuthenticationManager
和ClaimsAuthorizationManager
设置:
<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
为每个请求调用 my 并传入操作的 http 动词和资源的 URL,这是没有用的,因为我想手动确定何时使用查询和更改调用声明数据服务提供的拦截器。这就是我发现 Dominick 对问题的解释,建议编写一个自定义类和属性来替换ClaimsPrincipalPermission
. 一切顺利,该属性位于更改和查询拦截器上,并AuthorizationManager
使用我的自定义 URI 第二次调用我。
现在,问题是,对于 GET 请求,它可以顺利运行。由我忽略的AuthorizationManager
WCF 调用一次,第二次使用我处理的属性调用。但是,对于 POST 请求(只要我有一个更改拦截器),当AuthorizationManager
使用我的 URI 第二次调用 时,上下文中的主体是 aGenericPrincipal
而不是 aClaimsPrincipal
并且不包含我要检查的声明。
如何确保ClaimsPrincipal
每次调用时我总是得到我的 ClaimsTransformer (ClaimsAuthenticationManager) 生成的AuthorizationManager
?
更多信息 经过一番深入的谷歌搜索后,我缩小了问题的范围。如果我在从客户端调用 SaveChanges 方法时使用 SaveChangesOptions.Batch,我只会看到 GenericPrincipal。如果我不发送批量更新,我会正常返回 ClaimsPrincipal。所以,新问题;如何保留 ClaimsPrincipal 以进行批量更新?
我在 MSDN 线程(http://social.msdn.microsoft.com/Forums/en-US/35eb817d-363c-4a94-b9eb-351cd0d8567f/batch-update-and-impersonation-current-user)上找到了一些信息我需要在我的 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.