- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我们在 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/
我在我的一个应用程序中使用授权管理器,我的要求是将 AzMan 存储从一个位置复制到另一个位置。我的源位置是 Active Directory,目标是 xml,我有这两个路径。 当我创建一个 AzMa
我目前正致力于实现自定义 WCF OpenAuth AuthenticationManager,并且我已经成功完成了。但是,我现在的问题是用户无法通过身份验证时的响应页面。我希望用户收到带有 401(
我正在尝试使用 Thinktecture 示例构建示例 Web 应用程序 ResourceAuthorization来自 github。 现在我在用授权属性装饰的 Controller 中有一个 Ac
我正在使用 ThinkTecture's resource based authorization在我的 WebApi 中。 我正在尝试测试我需要检查功能内部访问的 Controller 之一。但是现
我们在 WCF 中使用自定义绑定(bind)来使用安全 token (SAML) 进行身份验证。我们发现我们正在服务器端并看到 TokenHandler(派生自 Saml11SecurityToken
我是一名优秀的程序员,十分优秀!