gpt4 book ai didi

WCF 通过 net.tcp 使用 token 身份验证,丢失 TokenHandler 和 AuthorizationManager 之间的声明

转载 作者:行者123 更新时间:2023-12-02 21:56:20 25 4
gpt4 key购买 nike

我们在 WCF 中使用自定义绑定(bind)来使用安全 token (SAML) 进行身份验证。我们发现我们正在服务器端并看到 TokenHandler(派生自 Saml11SecurityTokenHandler)正确处理和授权 token ,然后返回一个新的 ClaimsIdentity。

但是,当处理调用 AuthorizationManager.CheckAccessCore(派生自 IdentityModelServiceAuthorizationManager)时,操作Context.ServiceSecurityContext.PrimaryIdentity 是一个没有填充任何内容的 GenericIdentity。

我们有一个下面的绑定(bind)的 http 实现,它非常相似,并且工作正常,我们可以看到 token 正在验证并且 ClaimsIdentity 正在返回,然后我们观察到 AuthorizationManager 处理相同的身份并允许他们通过。

netTcp 绑定(bind)是基于代码的绑定(bind),如下所示:

    /// <summary>
/// NetTcp binding that supports a Saml token being passed
/// </summary>
public class SamlNetTcpBinding : CustomBinding
{
private readonly TcpTransportBindingElement _transportBindingElement;
private readonly BinaryMessageEncodingBindingElement _encodingBindingElement;
// private readonly SecurityBindingElement _securityBindingElement;

/// <summary>
/// Initializes a new instance of the <see cref="SamlNetTcpBinding"/> class.
/// </summary>
public SamlNetTcpBinding()
{
IssuerAddress = "http://www.myIssuerAddress.com/";

_transportBindingElement = new TcpTransportBindingElement()
{
TransferMode = TransferMode.Streamed, PortSharingEnabled = true
};
_encodingBindingElement = new BinaryMessageEncodingBindingElement();
}

/// <summary>
/// Returns a generic collection of the binding elements from the custom binding.
/// </summary>
/// <returns>
/// An <see cref="T:System.Collections.Generic.ICollection`1" /> object of type <see cref="T:System.ServiceModel.Channels.BindingElement" /> that contains the binding elements from the custom binding.
/// </returns>
public override BindingElementCollection CreateBindingElements()
{
return new BindingElementCollection()
{
new TransactionFlowBindingElement(TransactionProtocol.WSAtomicTransactionOctober2004),
CreateSecurityBindingElement(),
new SslStreamSecurityBindingElement(),
_encodingBindingElement,
_transportBindingElement
};
}

/// <summary>
/// Provide definition for the scheme.
/// </summary>
/// <returns>The URI scheme for transport used by the custom binding; or an empty string if there is no transport (<see cref="T:System.ServiceModel.Channels.TransportBindingElement" /> is null).</returns>
public override String Scheme
{
get { return "net.tcp"; }
}

/// <summary>
/// Gets or sets the issuer address.
/// </summary>
/// <value>
/// The issuer address.
/// </value>
public string IssuerAddress { get; set; }

/// <summary>
/// Create client side binding certificate.
/// </summary>
/// <returns>A security Binding element</returns>
private SecurityBindingElement CreateSecurityBindingElement()
{
var protectionParameters = new X509SecurityTokenParameters(
X509KeyIdentifierClauseType.Thumbprint, SecurityTokenInclusionMode.AlwaysToRecipient);

// Configure token issuance parameters.
var parameters = new IssuedSecurityTokenParameters(
SecurityTokenTypes.OasisWssSaml11TokenProfile11,
new EndpointAddress(IssuerAddress),
new BasicHttpBinding())
{
KeyType = System.IdentityModel.Tokens.SecurityKeyType.BearerKey,
InclusionMode = SecurityTokenInclusionMode.AlwaysToRecipient
};

var element = SecurityBindingElement.CreateIssuedTokenOverTransportBindingElement(parameters);
element.MessageSecurityVersion = MessageSecurityVersion.WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10;
element.EndpointSupportingTokenParameters.Endorsing.Add(protectionParameters);

return element;
}
}

非常感谢任何想法或建议。由于 .net 管道处理了大量的编排工作 - 很难确定身份在哪里丢失。我相当有信心 System.ServiceModel 在某个地方丢失了它,不明白的是为什么 net.tcp 传输会导致这种情况,而 http 不会。

谢谢

最佳答案

(供读者引用,我知道 Chubby Ass,我们已经离线讨论过这个问题,包括共享一些额外的代码,但我在这里发布我能提供的信息,以帮助其他可能遇到同样问题的人)

ServiceSecurityContext.PrimaryIdentity 仅当 ClaimsIdentity 是范围内唯一的时才返​​回它。如果存在超过 1 个身份,则它无法识别哪个是主要身份,因此返回通用身份。

在您的场景中,您在上下文中有 2 个身份:来自 SAML token 的声明身份,以及代表调用者附加的客户端证书的身份,这是 net.tcp 所需的东西,但对于 basicHttp 来说不需要用于身份验证。为了访问 ClaimsIdentity,您需要更新您的 ClaimsServiceAuthorizationManager,如下所示:

        var identity = securityContext.PrimaryIdentity as IClaimsIdentity;
if (identity == null)
{
// If there is more than 1 identity, for example if there is also a certificate then PrimaryIdentity will be null.
if (securityContext.AuthorizationContext.Properties.ContainsKey("Principal"))
{
var principal = securityContext.AuthorizationContext.Properties["Principal"] as IClaimsPrincipal;
if (principal != null)
{
identity = principal.Identity as IClaimsIdentity;
}
}

if (identity == null)
{
throw new InvalidOperationException("PrimaryIdentity identity is not an IClaimsIdentity");
}
}

关于WCF 通过 net.tcp 使用 token 身份验证,丢失 TokenHandler 和 AuthorizationManager 之间的声明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17726480/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com