gpt4 book ai didi

WCF 客户端使用证书和用户名/密码凭据?

转载 作者:行者123 更新时间:2023-12-01 09:39:56 25 4
gpt4 key购买 nike

我正在使用来自 ASP.NET 的公司内部的 Web 服务。我使用 svcutil.exe 连接到服务并从 wsdl 生成绑定(bind)和类。我能够连接到不需要身份验证的开发版本。现在我们正在添加安全性。我的新 URI 使用 https,但也需要用户凭据。

我对 WCF 很陌生,正在尝试确定配置它的方法。来 self 的reading on MSDN ,看来要走的路是使用。

更新:这是我一直在尝试的最新代码。这包含了来自答案的反馈:

 <system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="svcBehavior">
<serviceCredentials>
<serviceCertificate storeLocation="CurrentUser"
storeName="My"
x509FindType="FindByThumbprint"
findValue="xx xx xx etc"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding name="CustomerPaymentProgramSOAPBinding">
<security mode="TransportWithMessageCredential">
<message clientCredentialType="UserName" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="https://***URL***"
binding="wsHttpBinding" bindingConfiguration="CustomerPaymentProgramSOAPBinding"
contract="CppService.CustomerPaymentProgramService" name="CustomerPaymentProgramService">
</endpoint>
</client>
</system.serviceModel>

这里是调用代码:

using (var svc = new CustomerPaymentProgramServiceClient())
{
svc.ClientCredentials.UserName.UserName = "*******";
svc.ClientCredentials.UserName.Password = "*******";
var request = new GetServiceDataProgramRequest()
{
CustomerAccountId = Convert.ToInt64(customerAccountId)
};

svc.Open();
var response = new GetServiceDataProgramResponse();
var metaData = new RequestMetadata()
{
ClientIPAddress = "xx.xx.xx.xx",
TrackingNumber = "1",
UserID = "1"
};

svc.GetAccountData(metaData, request, out response);
}

我收到一条错误消息,指出我正在通过请求传递匿名凭据。使用更新的代码,现在我收到一个不同的异常:

更新:

在进行建议的更改并从 using block 中删除服务调用(根据 this 文章)后,我现在收到 MessageSecurityException:

Error message:
-$exception {"The HTTP request is unauthorized with client authentication scheme 'Anonymous'.
The authentication header received from the server was 'Basic realm=\"Spring Security Application\"'."}
System.Exception {System.ServiceModel.Security.MessageSecurityException}


Server stack trace:
at System.ServiceModel.Channels.HttpChannelUtilities.ValidateAuthentication(HttpWebRequest request, HttpWebResponse response, WebException responseException, HttpChannelFactory factory)
at System.ServiceModel.Channels.HttpChannelUtilities.ValidateRequestReplyResponse(HttpWebRequest request, HttpWebResponse response, HttpChannelFactory factory, WebException responseException)
at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Channels.SecurityChannelFactory`1.SecurityRequestChannel.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Security.SecuritySessionSecurityTokenProvider.DoOperation(SecuritySessionOperation operation, EndpointAddress target, Uri via, SecurityToken currentToken, TimeSpan timeout)
at System.ServiceModel.Security.SecuritySessionSecurityTokenProvider.GetTokenCore(TimeSpan timeout)
at System.IdentityModel.Selectors.SecurityTokenProvider.GetToken(TimeSpan timeout)
at System.ServiceModel.Security.SecuritySessionClientSettings`1.ClientSecuritySessionChannel.OnOpen(TimeSpan timeout)
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.OnOpen(TimeSpan timeout)
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.CallOpenOnce.System.ServiceModel.Channels.ServiceChannel.ICallOnce.Call(ServiceChannel channel, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.CallOnceManager.CallOnce(TimeSpan timeout, CallOnceManager cascade)
at System.ServiceModel.Channels.ServiceChannel.EnsureOpened(TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)\r\n\r\nException rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at [ServiceName].GetAccountData(svcRequest request)
at [ServiceName].GetAccountData(GetAccountDataRequest request)
in c:\\[Project]\\service references\\[ServiceName]\\reference.cs:line 3480
at c:\\[Project]\\service references\\[ServiceName](RequestMetadata RequestMetadata, ServiceRequest, ServiceResponse& ServiceResponse)
in c:\\[Project]\\service references\\[ServiceName]\\reference.cs:line 3487
at c:\\[Project]\\service references\\[ServiceName].CheckAccountForPaymentPlan(String customerAccountId)
in c:\\[Project]\\service references\\[ServiceName]\\\\PlanCheckService.cs:line 32

最佳答案

TransportWithMessageCredential ,您指定您将使用消息安全来保护各个消息,这需要客户端凭据(用户名和密码)。您需要类似于 msdn 链接中的配置的内容,如下所示:

<wsHttpBinding>
<binding name="WsHttpBinding_ICalculator">
<security mode="TransportWithMessageCredential" >
<message clientCredentialType="UserName" />
</security>
</binding>
</wsHttpBinding>

这不需要为客户端凭据指定证书。传输安全性(使用 https 和有效的 ssl 证书)的工作方式与网站相同,它不需要用户提供额外的凭据/证书。来自受信任的证书颁发机构的有效证书安装在服务器上(客户端机器能够验证它们)并且握手过程保护 channel 。这不需要您设置clientCrdentials在配置中。您只需要安装一个有效的证书(或为 dev 测试证书)并将服务器配置配置为指向它,类似于:

<behaviors>
<serviceBehaviors>
<behavior name="mySvcBehavior">
<serviceCredentials>
<serviceCertificate findValue="contoso.com"
x509FindType="FindByIssuerName" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>

尝试删除 < transport clientCredentialType="Certificate" />从您的服务器配置作为启动器,更新服务引用并确保您的证书正常工作和配置正确。如果仍有问题,请发布您的实际异常和更多配置。

要获得良好的 WCF 源,请尝试:CodePlex ,当我开始使用 WCF 时,它对我的​​帮助无穷无尽。不同的应用场景提供了有用的 list ,以帮助确保您不会错过配置中的任何步骤。

祝你好运

更新:

一旦 channel 出现故障,就需要重新创建它,因为在它被重置之前您将无法与服务通信。所以添加一个检查来重新创建它:

If svc.State = CommunicationState.Faulted Then....

尝试删除 svc.Open()线,因为我从来没有真正使用过。我检查了 msdn 的使用细节,但得到了大约 2 行无用的信息。设置服务后,您应该能够与它进行通信,而无需专门打开它。不确定这是否真的会有所作为?!

其他要检查的事项:- 您可以右键单击服务并在浏览器中查看没有问题吗?- 在 IIS您可以在目录安全中查看证书而没有任何问题吗?- 在进行服务调用之前进行调试并检查凭据是否正确分配。- 检查服务器事件查看器以获取它可能与请求一起记录的任何信息(如果它到达那么远)。

另外,这里有一些我使用 ex.GetBaseException.GetType 来确定问题的异常情况。 :

ServiceModel.EndpointNotFoundException

  • 服务器连接问题 - IIS 未运行或服务器名称无效

ServiceModel.Security.MessageSecurityException

  • 基本异常 - ServiceModel.FaultException

    • "FailedAuthentication "- 用户输入的凭据错误

    • "InvalidSecurity "- 数据库错误 - 任一帐户无权访问数据库,Web 配置中的数据库名称不正确,数据库中的用户密码已过期

    • InvalidRequest” - 证书可访问性问题 - 检查服务帐户是否有权访问证书

基本异常 - Net.WebException

  • 未授权访问 401 - 检查 IIS 中的匿名访问是否已打开

基本异常 - IdentityModel.Tokens.SecurityTokenValidationException

  • 在 IIS 中未分配服务证书

基本异常 - System.ServiceModel.CommunicationException

  • 身份与服务器证书不匹配 - 例如在开发环境中,证书名为“localhost”,因此如果您输入 PC 号码或 IP 地址进行服务,您会看到此内容

关于WCF 客户端使用证书和用户名/密码凭据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1165078/

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