WCF와 연결하여 사용자 이름/비밀번호로 인증 된 웹 서비스에 연결
-
03-07-2019 - |
문제
Visual Studio 2008을 사용하여 웹 서비스 프록시를 만들었고 App.config에서 다음 항목을 만들었습니다.
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="MyNameHandlerSoapBinding" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://www.***/***/***"
binding="basicHttpBinding" bindingConfiguration="MyNameHandlerSoapBinding"
contract="***.MyNameHandler" name="MyName">
</endpoint>
</client>
</system.serviceModel>
웹 서비스에는 사용자 이름/비밀번호 인증이 있으므로 여기 어딘가에 추가해야합니다.
나는 WCF 문서의 바다에서 약간 길을 잃었습니다. 나는 인증 요소를 추가 할 수 있도록 Basichttpbinding에서 WSHTTPBinding 또는 CustomBinding으로 변경해야한다고 생각하지만 실제로 이해하지 못합니다. 누구든지 빠른 팁이나 그렇게하는 방법을 말하는 유용한 링크를 줄 수 있습니까?
편집하다:
보안 섹션을 다음으로 변경했습니다.
<security mode="Transport">
<transport clientCredentialType="Basic" proxyCredentialType="None"
realm="" />
</security>
코드에 추가 :
ws.ClientCredentials.UserName.UserName = "";
ws.ClientCredentials.UserName.Password = "";
이제 자격 증명을 사용하는 것 같지만 오류가 발생합니다.
제공된 URI 체계 'http'는 유효하지 않은 URI 예상 'https'입니다.
이것이 올바른 방법인지조차 모르겠습니다 ...
해결책
여기에 미래의 독자를위한 솔루션을 게시합니다.
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="MyHandlerSoapBinding" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Basic" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://www.***/***/***/MyHandler"
binding="basicHttpBinding" bindingConfiguration="MyHandlerSoapBinding"
contract="***.MyHandler" name="MyHandler">
</endpoint>
</client>
</system.serviceModel>
결국 나는 기본 Basichttpbinding을 사용할 수 있습니다. 질문에 게시 된 코드와 유일한 차이점은 다음과 같습니다. 보안 노드.
또한 참고하십시오 모드 = "TransportCredentially" 옵션, 이렇게하면 사용자 이름/비밀번호를 사용하여 보낼 수 있습니다. http
대신에 https
. 이것은 내가 사용하는 환경을 테스트하는 데 필요합니다. 나중에 분명히 당신은 선호합니다 https
자격 증명을 보냅니다.
나중에 코드로는 사용자 이름/비밀번호를 입력합니다.
var ws = new ***.MyHandlerClient("MyHandler");
ws.ClientCredentials.UserName.UserName = "myUsername";
ws.ClientCredentials.UserName.Password = "myPassword";
var result = ws.executeMyMethod();
다른 팁
오류 메시지가 맞습니다. WCF는 보호되지 않은 프로토콜을 통해 사용자 이름과 암호를 전송할 수 없습니다. 귀하의 웹 서비스 ~ 해야 하다 https를 사용하고 있습니다 (승무원 SSL 인증서 포함)
SSL 인증서가 있으면 자격 증명이 전송되는 방법, 운송 또는 보안 및 자격 증명 유형에 대한 여러 옵션에 대한 두 가지 옵션이 있습니다. MSDN은 a 좋은 가이드 모든 다양한 옵션에.
I had the same problem and tried the solution above Somehow this didn't work for me I was keep getting the message "No WS-Security header found"
After a long time of testing and trying I manage to get it work I added the header code in the client as below and then it works!
<client>
<endpoint address="http://your.service.com" binding="basicHttpBinding" bindingConfiguration="XXXBinding" contract="contract.XXX" name="XXXPort">
<headers xmlns:wsse="http://your.xsd">
<wsse:Security mustUnderstand="1">
<wsse:UsernameToken>
<tenant>XXX</tenant>
<wsse:Username>XXX</wsse:Username>
<wsse:Password Type="http://www.xxxx.com/wss#PasswordText">XXX</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</headers>
</endpoint>
</client>