【问题标题】:ClaimsPrincipal is null when it reaches WCF ServiceClaimsPrincipal 在到达 WCF 服务时为空
【发布时间】:2023-04-06 02:09:01
【问题描述】:

我目前正在使用以下方法实施联合身份验证解决方案: 用于发行令牌的被动 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 只是设置 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 也不包含。

有什么想法吗?

【问题讨论】:

    标签: wcf wif


    【解决方案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 }); 
     }
    
    }
    

    【讨论】:

      【解决方案2】:

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

      HTH

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-03-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-02-20
        相关资源
        最近更新 更多