我正在开发一个使用web服务的客户端。端点是HTTPS。当我尝试登录时会出现此异常。为什么?
这是的方法
BasicHttpsBinding binding = new BasicHttpsBinding();
binding.Security.Mode = BasicHttpsSecurityMode.Transport;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
binding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;
binding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.Certificate;
var ea = new EndpointAddress(new Uri($@"https://endpoint"));
WSPDDClient client = new WSPDDClient(binding, ea);
client.ClientCredentials.UserName.UserName = "username";
client.ClientCredentials.UserName.Password = "password";
client.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
client.ClientCredentials.ClientCertificate.SetCertificate(StoreLocation.LocalMachine, StoreName.My, X509FindType.FindBySubjectName, "certificatename");
WSPDD.login login1 = new WSPDD.login()
{
login1="username",
password="password"
};
try
{
client.Open();
WSPDD.loginResponse resLogin = client.login(login1);
if (resLogin.@return.success)
{
}
else
{
Debug.WriteLine("Err {0}", resLogin.@return.error);
}
}
catch(Exception ex)
{
Debug.WriteLine("Err {0}", ex);
}
这是web.config
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="WSPDDBinding" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://endpoint"
binding="basicHttpBinding" bindingConfiguration="WSPDDBinding"
contract="WSPDD" name="WSPDDPort" />
</client>
例外情况是:
HTTP请求未使用"匿名"客户端身份验证方案进行授权。从服务器接收到的身份验证标头:'Mutual SSL realm=\"WSO2 API Manager\",error=\"无效令牌\",Errordescription=\"访问令牌过期\"'。">
上出现异常
WSPDD.loginResponse resLogin = client.login(login1);
所有这些代码片段都位于客户端,并且某些设置是重复的,例如Basichttpbinding配置。代码段中的配置设置与Webconfig
中的不一致
调用WCF服务的常见方法是通过添加服务引用来生成客户端代理,这也会在客户端的配置文件中带来与服务器端一致的绑定设置
从客户端发生的错误来看,代码片段中的绑定配置应该是正确的,并且与服务器端相对应。
BasicHttpsBinding binding = new BasicHttpsBinding();
binding.Security.Mode = BasicHttpsSecurityMode.Transport;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
换句话说,服务器使用证书对客户端进行身份验证,客户端在调用远程服务时应提供客户端证书。在这个过程中,我们应该在服务器端和客户端之间建立信任关系
https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/transport-security-with-certificate-authentication
如果有什么我可以帮忙的,请随时告诉我。
感谢您的回复。我按照你的建议做了,亚伯拉罕。
WSPDD.SimogWSPDDClient client = new WSPDD.SimogWSPDDClient();
WSPDD.login login1 = new WSPDD.login
{
login1 = "username",
password = "passowrd"
};
WSPDD.loginResponse loginResponse = new WSPDD.loginResponse();
loginResponse = client.login(login1);
if(loginResponse.@return.success)
{
}
else
{
Console.WriteLine("Err {0}", loginResponse.@return.error);
}
end Web.config
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="endpointCredentialBehavior">
<clientCredentials>
<clientCertificate findValue="+++certificatename+++"
storeLocation="LocalMachine"
storeName="My"
x509FindType="FindBySubjectName" />
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<!-- configure wsHttpbinding with Transport security mode
and clientCredentialType as Certificate -->
<binding name="SimogWSPDDBinding">
<security mode="Transport">
<transport clientCredentialType="Certificate"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="https://*****/****/1.0.0"
binding="wsHttpBinding" bindingConfiguration="SimogWSPDDBinding"
contract="WSPDD.SimogWSPDD" name="SimogWSPDDPort" behaviorConfiguration="endpointCredentialBehavior" />
</client>
同一代码行(loginResponse = client.login(login1);
(中的所有错误为:
System.ServiceModel.Security.MessageSecurityException
HResult=0x80131501
Messaggio=La richiesta HTTP non è autorizzata con lo schema di autenticazione client 'Anonymous'. Intestazione di autenticazione ricevuta dal server: 'Mutual SSL realm="WSO2 API Manager", error="invalid token", error_description="The access token expired"'.
Origine=mscorlib
Analisi dello stack:
in System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
in System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
in ANAC_WS_3.WSPDD.SimogWSPDD.login(loginRequest request)
in ANAC_WS_3.WSPDD.SimogWSPDDClient.ANAC_WS_3.WSPDD.SimogWSPDD.login(loginRequest request) in C:UsersFrancescosourcereposANAC_WS_3ANAC_WS_3Connected ServicesWSPDDReference.cs: riga 14534
in ANAC_WS_3.WSPDD.SimogWSPDDClient.login(login login1) in C:UsersFrancescosourcereposANAC_WS_3ANAC_WS_3Connected ServicesWSPDDReference.cs: riga 14540
in ANAC_WS_3.Controllers.HomeController.Index() in C:UsersFrancescosourcereposANAC_WS_3ANAC_WS_3ControllersHomeController.cs: riga 25
in System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters)
in System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)
in System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
in System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c.<BeginInvokeSynchronousActionMethod>b__9_0(IAsyncResult asyncResult, ActionInvocation innerInvokeState)
in System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`2.CallEndDelegate(IAsyncResult asyncResult)
in System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
in System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult)
in System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<>c__DisplayClass11_0.<InvokeActionMethodFilterAsynchronouslyRecursive>b__0()
in System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<>c__DisplayClass11_2.<InvokeActionMethodFilterAsynchronouslyRecursive>b__2()
Eccezione interna 1:
WebException: Errore del server remoto: (401) Non autorizzato.