gpt4 book ai didi

c# - 使用自定义 ClientCredentials : What is the clientCredentialType to use? 的 WCF 身份验证

转载 作者:IT王子 更新时间:2023-10-29 04:22:20 27 4
gpt4 key购买 nike

我不得不放弃基本的 WCF UserName/Pwd 安全性并实现我自己的自定义客户端凭据,以保存默认情况下提供的更多信息。

我通过了 this MSDN article ,但我错过了一些东西,因为它不起作用。

首先,我有一些提供自定义 ClientCredentialsSecurityTokenManager 的自定义 ClientCredentials:

public class CentralAuthCredentials : ClientCredentials
{
public override System.IdentityModel.Selectors.SecurityTokenManager CreateSecurityTokenManager()
{
return new CentralAuthTokenManager(this);
}
}

public class CentralAuthTokenManager : ClientCredentialsSecurityTokenManager
{
private CentralAuthCredentials credentials;

public CentralAuthTokenManager(CentralAuthCredentials creds) : base(creds)
{
this.credentials = creds;
}

public override SecurityTokenProvider CreateSecurityTokenProvider(SecurityTokenRequirement tokenRequirement)
{
if (this.IsIssuedSecurityTokenRequirement(tokenRequirement) || tokenRequirement.TokenType == CentralAuthToken.TOKEN_TYPE)
return new CentralAuthTokenProvider(credentials.UserId, credentials.UserPassword, credentials.ImpersonateId, credentials.LoginType);
else
return base.CreateSecurityTokenProvider(tokenRequirement);
}

public override SecurityTokenAuthenticator CreateSecurityTokenAuthenticator(SecurityTokenRequirement tokenRequirement, out SecurityTokenResolver outOfBandTokenResolver)
{
outOfBandTokenResolver = null;
if (this.IsIssuedSecurityTokenRequirement(tokenRequirement) || tokenRequirement.TokenType == CentralAuthToken.TOKEN_TYPE)
return new CentralAuthTokenAuthenticator();
else
return base.CreateSecurityTokenAuthenticator(tokenRequirement, out outOfBandTokenResolver);
}

public override SecurityTokenSerializer CreateSecurityTokenSerializer(SecurityTokenVersion version)
{
return new CentralAuthTokenSerializer();
}
}

现在,当我运行该应用程序时,会创建我的自定义凭据和 token 管理器。
但是,在方法中:
CreateSecurityTokenProvider(SecurityTokenRequirement tokenRequirement)
{
...
}

tokenRequirement.TokenType 与我的自定义 token 不同。这带来了我的 第一个问题 :WCF 怎么知道 token 要求是什么?

还有方法:
public override SecurityTokenSerializer CreateSecurityTokenSerializer(SecurityTokenVersion version)
{
return new CentralAuthTokenSerializer();
}

客户端会调用一次,但返回的 token 序列化器上的任何方法都不会被调用。这向我表明自定义 token 永远不会通过网络发送。我认为这是因为对 CreateSecurityTokenProvider() 的调用从未返回我的自定义 token 提供程序,因为 SecurityTokenRequirement 从未传入指示需要我的自定义 token 。

在客户端,我有:
public class CentralAuthorizationManagerClient : ClientBase<ICentralAuthorizationManager>, ICentralAuthorizationManager, IDisposable
{
public PFPrincipal GenerateToken()
{
if (!this.ChannelFactory.Endpoint.Behaviors.Contains(typeof(CentralAuthCredentials)))
throw new ArgumentException("Must set CentralAuthCredentials before calling this method.");
return base.Channel.GenerateToken();
}

public PFPrincipal GenerateToken(CentralAuthToken token)
{
this.ChannelFactory.Endpoint.Behaviors.Remove<ClientCredentials>();
this.ChannelFactory.Endpoint.Behaviors.Add(new CentralAuthCredentials(token));
return this.GenerateToken();
}

这些方法基本上应该从端点中删除默认凭据并附加我的自定义 CentralAuthCredentials 的新实例。 (我从某处的 MSDN 文章中获取了这个删除/添加组合)。

在配置中:
    <behaviors>
<endpointBehaviors>
<behavior name="Server2ServerEndpointBehavior">
<clientCredentials type="MyApp.Security.CentralAuthCredentials, MyApp">
<clientCertificate findValue="localhost" x509FindType="FindBySubjectName" storeLocation="CurrentUser" storeName="My" />
<serviceCertificate>
<authentication certificateValidationMode="None" revocationMode="NoCheck" />
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>

<bindings>
<wsHttpBinding>
<binding name="wsHttpServer2Server">
<security mode="Message">
<message clientCredentialType="UserName" />
</security>
</binding>
</wsHttpBinding>
</bindings>

请注意,行为的 clientCredentials 类型设置为我的自定义客户端凭据。但是,目前我仍然将绑定(bind)的 clientCredentialType 设置为“UserName”。这带来了我的 第二个问题 :clientCredentialType="应该怎么办?"如果我使用自定义凭据,则设置为?根据 MSDN,消息安全的可用值包括:无、Windows、用户名、证书和已颁发的 token 。

有任何想法吗?希望我只是错过了一些简单的东西?整个实现还有 6 个类,但我试图只包括理解情况所需的位......

更新 #1:

我一整天都在研究这个,多亏了一些消息来源,我意识到我所缺少的部分是 this page 的最后一步。 ,这是将 TokenParameters 添加到绑定(bind)中,以便绑定(bind)知道 token 的外观。那是我最初的第一个问题的答案; “到底是什么设置了 token 要求?”答案:分配给绑定(bind)的 TokenParameters。

所以现在我添加了以下扩展,它在绑定(bind)上设置 TokenParameters:
public sealed class CentralAuthTokenBindingExtension : BindingElementExtensionElement
{
public CentralAuthTokenBindingExtension()
: base()
{
}

public override Type BindingElementType
{
get { return typeof(SymmetricSecurityBindingElement); }
}

protected override System.ServiceModel.Channels.BindingElement CreateBindingElement()
{
X509SecurityTokenParameters protectionParams = new X509SecurityTokenParameters();
protectionParams.InclusionMode = SecurityTokenInclusionMode.Never;

SymmetricSecurityBindingElement innerBindingElement = new SymmetricSecurityBindingElement();
innerBindingElement.EndpointSupportingTokenParameters.SignedEncrypted.Add(new CentralAuthTokenParameters());
//innerBindingElement.MessageProtectionOrder = MessageProtectionOrder.SignBeforeEncrypt;
innerBindingElement.ProtectionTokenParameters = protectionParams;

return innerBindingElement;
}
}

<extensions>
<bindingElementExtensions>
<add name="CentralAuthCreds" type="MyApp.Security.Configuration.CentralAuthTokenBindingExtension, MyApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</bindingElementExtensions>
</extensions>

<bindings>
<customBinding>
<binding name="wsHttpServer2Server">
<CentralAuthCreds />
<binaryMessageEncoding />
<httpTransport />
</binding>
</customBinding>
</bindings>

嗯,这让我更进一步。现在我在服务器上收到一个新的异常:
"The security token manager cannot create a token authenticator for requirement ..."

看起来 WCF 正在使用一些默认 token 管理器来尝试处理我的自定义 token ,而不是我的自定义 token 处理程序(我的自定义 token 处理程序的构造函数从未被调用)。我认为这是因为对于客户端,我有以下配置:
<endpointBehaviors>
<behavior name="Server2ServerEndpointBehavior">
<clientCredentials type="MyApp.Security.CentralAuthCredentials, MyApp">

但是在服务器上,我没有任何等价物可以让它知道自定义客户端凭据。所以, 新问题 :在服务器的配置中我应该告诉它自定义 ClientCredentials 是什么?

更新 #2:

好吧,我终于想出了更多的谜题。我只实现了 ClientCredentials 实现,认为客户端发送凭据,仅此而已。客户端不验证服务,所以我不需要自定义 ServiceCredentials。好吧,我错了。指定的 ServiceCredentials 验证来自 ClientCredentials 的 token ,反之亦然。所以我只需要添加一个自定义的 ServiceCredentials 实现,它传递相同的 TokenSerializer 和 TokenAuthenticator 类。

关于下一个问题:WCF 现在忽略我在配置中指定的 x509 证书,这些证书与 UserName auth 一起工作正常。我要为这个问题打开一个全新的问题!

最佳答案

我在我正在处理的应用程序中遇到了类似的问题,不幸的是我放弃了,因为我无法使自定义凭据正常工作。我现在使用用户名/密码(客户端凭据)和证书(服务凭据),并将自定义加密的soap header 添加到服务调用中以传递附加信息,例如用户ID等。

关于c# - 使用自定义 ClientCredentials : What is the clientCredentialType to use? 的 WCF 身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/563037/

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