我使用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
在这里是空的。
任何想法?
嗯-除了你正在做的是非常罕见的做法-在WCF管道中只有一个地方你可以安全地设置Thread.CurrentPrincipal。当PrincipalPermissionMode设置为Custom时,这是在服务授权管理器中。
通常您宁愿将声明作为安全令牌(如SAML)的一部分传递,并让WCF为您做服务器端管道。
在旧WCF服务切换到https时遇到了这个问题(奇怪的是,在http下没有发生)。快速而肮脏的解决方法是将principalPermissionMode
设置为None
。
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceAuthorization principalPermissionMode="None" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
您可能有很好的理由手动执行此操作,但是在wcf中传递身份是由wsFederationHttpBinding开箱即用处理的。您可以在WIF SDK中或在http://msdn.microsoft.com/nl-be/library/aa355045.aspx上找到示例。