当到达WCF服务时,ClaimsPrincipal为空

3
我目前正在实施联合身份验证解决方案,其中包括: 使用被动STS发放令牌、托管Silverlight应用程序的网站以及为Silverlight应用程序提供WCF服务。
到目前为止,我已经能够:
- 被重定向到STS - 登录并被重定向到网站 - 通过访问HttpContext.Current.User.Identity as IClaimsIdentity;在网站上显示声明
在网站的web.config中,我已经添加了两个所需的WIF模块(在IIS 7下)。
<modules runAllManagedModulesForAllRequests="true">

        <add name="WSFederationAuthenticationModule" type="Microsoft.IdentityModel.Web.WSFederationAuthenticationModule, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="managedHandler"/>
        <add name="SessionAuthenticationModule" type="Microsoft.IdentityModel.Web.SessionAuthenticationModule, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="managedHandler"/>

    </modules>

我还配置了web.config文件中的Microsoft.IdentityModel部分,使用了自己实现的ClaimsAuthenticationManager和ClaimsAthorizationManager。

<service name="Rem.Ria.PatientModule.Web.WebService.PatientService">
        <claimsAuthenticationManager type ="Rem.Infrastructure.WIF.RemClaimsAuthenticationManager"/>
        <claimsAuthorizationManager type ="Rem.Infrastructure.WIF.RemClaimsAuthorizationManager"/>
      </service>

我的ClaimsAuthenticationManager只是在提供有效Principal情况下将Thread.CurrentPrincipal设置为有效Principal。

class RemClaimsAuthenticationManager : ClaimsAuthenticationManager
    {
        public override IClaimsPrincipal Authenticate ( string resourceName, IClaimsPrincipal incomingPrincipal )
        {

            if ( incomingPrincipal.Identity.IsAuthenticated )
            {
                Thread.CurrentPrincipal = incomingPrincipal;
            }
            return incomingPrincipal;
        }
    }
}

问题在于当我的ClaimsAuthorizationManager被调用时,context.Principal.Identity中不包含有效的带有声明的身份信息,Thread.CurrentPrincipal也是如此。有什么想法吗?
2个回答

5

您不需要设置Thread.CurrentPrincipal,因为会话模块会为您完成此操作。 您需要通过HttpContext.Current.User访问它,因为Thread.Principal通常在与访问您的服务的线程不同的线程上设置,因为它是IIS中的两个不同模块。 我们在即将推出的书籍中有一个示例,您可以在我们的Codeplex网站上查看。

希望对您有所帮助。


1
以下示例代码展示了一个继承ClaimsAuthenticationManager的样本类。它只接收传入的IClaimsPrincipal并通过声明进行传递,除了Name声明被修改。这不会像您的示例中那样在当前线程上设置CurrentPrincipal。
我的测试实现如下:
public class CustomClaimsAuthenticationManager : ClaimsAuthenticationManager
{
public CustomClaimsAuthenticationManager()
{

}

public override IClaimsPrincipal Authenticate(string resourceName, 
IClaimsPrincipal   incomingPrincipal)
{
    var outgoingIdentity = GetClaimsAsPassthrough(incomingPrincipal);
    return outgoingIdentity; 
}

private IClaimsPrincipal GetClaimsAsPassthrough(IClaimsPrincipal incomingPrincipal)
{
    if (!incomingPrincipal.Identity.IsAuthenticated)
    {
        return incomingPrincipal; 
    }

    var ingoingClaims = incomingPrincipal.Identity as IClaimsIdentity; 

    ClaimsIdentity outgoingIdentity = new ClaimsIdentity(new List<Claim>
    {
        new Claim(ClaimTypes.Name, (incomingPrincipal.Identity.Name + " 
        a very cool guy"))
    }, incomingPrincipal.Identity.AuthenticationType);

    foreach (var claim in ingoingClaims.Claims.Where(
    c => c.ClaimType != ClaimTypes.Name))
    {
        outgoingIdentity.Claims.Add(claim.Copy()); 
    }

    return new ClaimsPrincipal(new List<ClaimsIdentity> { outgoingIdentity }); 
 }

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接