带有 WIF 4.5 的 WCF 数据服务;没有为 POST 请求设置主体

Posted

技术标签:

【中文标题】带有 WIF 4.5 的 WCF 数据服务;没有为 POST 请求设置主体【英文标题】:WCF Data Service with WIF 4.5; Principal not set for POST requests 【发布时间】:2013-06-29 19:34:06 【问题描述】:

在关注 Dominick Baier 的 Pluralsight 课程和有关 WIF 4.5 的博客之后,我仍然遇到无法解决的问题。我正在使用 WCF 数据服务和使用 WIF 4.5 的基于声明的授权。

我在 web.config 中设置了 ClaimsAuthenticationManagerClaimsAuthorizationManager

<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,这是没有用的,因为我想手动确定声明的时间使用数据服务提供的查询和更改拦截器调用。这就是我发现Dominick 的explanation 建议编写自定义类和属性来替换ClaimsPrincipalPermission 的问题的地方。一切顺利,该属性位于更改和查询拦截器上,并使用我的自定义 URI 第二次调用我的AuthorizationManager

现在,问题是,对于 GET 请求,它可以顺利运行。 AuthorizationManager 被 WCF 调用一次,我忽略它,第二次使用我处理的属性。但是,对于 POST 请求(只要我有更改拦截器),当使用我的 URI 第二次调用 AuthorizationManager 时,上下文中的主体是 GenericPrincipal 而不是 ClaimsPrincipal 并且不包含我的声称要检查。

我如何确保每次调用AuthorizationManager 时都能获得我的ClaimsTransformer (ClaimsAuthenticationManager) 生成的ClaimsPrincipal

更多信息 经过一些密集的谷歌搜索后,我缩小了问题的范围。如果我在从客户端调用 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.

【问题讨论】:

@leastprivilege 能否请您花点时间提供您的建议? 【参考方案1】:

问题已解决,这是确保批处理请求使用 WCF 数据服务在 WIF 4.5 中正常工作的正确配置

<behavior>
  <serviceCredentials useIdentityConfiguration="true" />
  <serviceAuthorization principalPermissionMode="Always" impersonateOnSerializingReply="true" />
</behavior>

【讨论】:

以上是关于带有 WIF 4.5 的 WCF 数据服务;没有为 POST 请求设置主体的主要内容,如果未能解决你的问题,请参考以下文章

如何解决此 WIF/WCF 异常?

在使用 WIF/Geneva 的应用程序中处理使用 WCF 服务的凭据

如何将(声明)安全令牌传递给启用 WIF 的 WCF 服务?

使用 ADFS2 作为 IP 使用 WIF 保护后端 WCF 服务

ASP.Net WCF 服务的 Thread.CurrentPrincipal 被联邦 (WIF) 环境中的某些拦截器丢弃

wsFederationHttpBinding over net.tcp