Thread.CurrentPrincipal中的声明正在丢失,这些声明在WCF中的AfterReceiveRequest中设置

时间:2013-05-05 17:05:38

标签: wcf wif endpoint idispatchmessageinspector iclientmessageinspector

我正在使用Microsoft.IdentityModel.dll来设置&在WCF中获取声明。我已经实施了MessageInspectors来设置声明。因此,我在客户端为下面的请求标头添加了ClaimsIdentity

public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel)
{
    var claims = new List<Claim> { new Claim(UserIdClaim, "12345"), };
    ClaimsIdentity claimsIdentity = new ClaimsIdentity(claims);
    MessageHeader<ClaimsIdentity> header = new MessageHeader<ClaimsIdentity>(claimsIdentity);
    var untypedHeader = header.GetUntypedHeader(ClaimsName, ClaimsNameSpace);
    request.Headers.Add(untypedHeader);

    return null;
}

服务方面,

public object AfterReceiveRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel, System.ServiceModel.InstanceContext instanceContext)
{
    ClaimsIdentity claimsIdentity = request.Headers.GetHeader<ClaimsIdentity>(ClaimsName, ClaimsNameSpace);
    var claimsIdentitylst = new ClaimsIdentityCollection(new List<IClaimsIdentity> { claimsIdentity });
    IClaimsPrincipal claimsPrincipal = new ClaimsPrincipal(claimsIdentitylst);
    Thread.CurrentPrincipal = claimsPrincipal;

    return null;
}

我正在尝试访问方法实现中的声明值(OperationContract),这些声明值在AfterReceiveRequest中设置,如下所示。但Thread.CurrentPrincipal中未提及这些声明。

var userIdClaim = ((IClaimsIdentity)Thread.CurrentPrincipal.Identity).Claims.First(c => c.ClaimType == UserIdClaim);

userIdClaim在这里为空。

有什么想法吗?

2 个答案:

答案 0 :(得分:3)

嗯 - 除了你正在做的事情是非常罕见的做法 - 在WCF管道中只有一个地方你可以安全地设置Thread.CurrentPrincipal。当PrincipalPermissionMode设置为Custom时,它位于服务授权管理器中。

通常,您宁愿将声明作为安全令牌(如SAML)的一部分传递,并让WCF为您执行服务器端管道。

答案 1 :(得分:0)

您可能有充分的理由手动执行此操作,但在wcf中传递标识是使用wsFederationHttpBinding开箱即用的。您可以在WIF SDK中找到示例,也可以在http://msdn.microsoft.com/nl-be/library/aa355045.aspx在线找到。