성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] 아쉽게도, 커뮤니티는 아니고 개인 블로그입니다. ^^
[정성태] 질문이 잘 이해가 안 됩니다. 우선, 해당 소스코드에서 ILis...
[양승조
] var대신 dinamic으로 선언해서 해결은 했습니다. 맞는 해...
[양승조
] 또 막혔습니다. ㅠㅠ var list = props[i].Ge...
[양승조
] 아. 감사합니다. 어제는 안됐던것 같은데....정신을 차려야겠네...
[정성태] "props[i].GetValue(props[i])" 코드에서 ...
[정성태] 저렇게 조각 코드 말고, 실제로 재현이 되는 예제 프로젝트를 압...
[정성태] Modules 창(Ctrl+Shift+U)을 띄워서, 해당 Op...
[정성태] 만드실 수 있습니다. 단지, Unity 엔진 내의 스크립트와 W...
[공진영] 안녕하세요 좋은글 감사합니다. 현재 제가 wpf로 관제 모...
글쓰기
제목
이름
암호
전자우편
HTML
홈페이지
유형
제니퍼 .NET
닷넷
COM 개체 관련
스크립트
VC++
VS.NET IDE
Windows
Team Foundation Server
디버깅 기술
오류 유형
개발 환경 구성
웹
기타
Linux
Java
DDK
Math
Phone
Graphics
사물인터넷
부모글 보이기/감추기
내용
<div style='display: inline'> <h1 style='font-family: Malgun Gothic, Consolas; font-size: 20pt; color: #006699; text-align: center; font-weight: bold'>basicHttpBinding + 사용자 정의 인증 구현</h1> <p> <br /> 예전에도 WCF의 사용자 정의 인증 구현 예제를 소개해 드렸는데요.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > WCF 사용자 정의 인증 구현 예제 ; <a target='tab' href='http://www.sysnet.pe.kr/2/0/864'>http://www.sysnet.pe.kr/2/0/864</a> </pre> <br /> 위의 예제는 다음과 같은 특징들이 있습니다.<br /> <br /> <ul> <li>netTcpBinding</li> <li>독립실행형 EXE에서 WCF 서버 호스팅</li> <li><security mode="Message" /> 사용</li> <li>사용자 정의 인증 사용</li> </ul> <br /> 하지만, 이번에는 다음과 같은 특징을 가진 WCF 예제를 소개해드릴려고 합니다.<br /> <br /> <ul> <li>basicHttpBinding</li> <li>IIS / HTTPS 사용</li> <li><security mode="TransportWithMessageCredential" /> 사용</li> <li>사용자 정의 인증 사용</li> </ul> <br /> <hr style='width: 50%' /><br /> <br /> 단적으로 말해서, 이번 글은 제가 기존에 써 두었던 "<a target='tab' href='http://www.sysnet.pe.kr/2/0/864'>WCF 사용자 정의 인증 구현 예제</a>"에서 다음의 글에 나오는 요소를 더하면 됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Username Authentication over basicHttpBinding with WCF’s ChannelFactory Interface ; <a target='tab' href='http://nirajrules.wordpress.com/2009/05/22/username-over-https-custombinding-with-wcf%E2%80%99s-channelfactory-interface/'>http://nirajrules.wordpress.com/2009/05/22/username-over-https-custombinding-with-wcf%E2%80%99s-channelfactory-interface/</a> </pre> <br /> 처음부터 예제를 만들기보다는, 지난번 글에 실린 예제 코드에서 살을 붙이는 식으로 진행해 볼 텐데 이를 위해 우선 다음의 예제 코드를 다운로드합니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > WcfUserName.zip ; <a target='tab' href='http://www.sysnet.pe.kr/bbs/DownloadAttachment.aspx?fid=529&boardid=331301885'>http://www.sysnet.pe.kr/bbs/DownloadAttachment.aspx?fid=529&boardid=331301885</a> </pre> <br /> 솔루션 파일을 Visual Studio IDE에서 로드한 후 웹 애플리케이션을 하나 생성하고 기존의 UserNamePasswordAuth 프로젝트를 참조 추가 및 예제용으로 TestService.svc 서비스를 하나 생성합니다.<br /> <br /> 다음으로 TestService.svc에 대한 사용자 정의 인증 구현 설정을 web.config에 다음과 같이 추가해 줍니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > <system.serviceModel> <services> <service name="WebApplication1.TestService" behaviorConfiguration="TestServiceBehavior"> <endpoint address="" binding="basicHttpBinding" bindingConfiguration="basicHttpBindingConfiguration" contract="WebApplication1.ITestService" /> </service> </services> <bindings> <basicHttpBinding> <binding name="basicHttpBindingConfiguration"> <span style='color: blue; font-weight: bold'> <security mode="TransportWithMessageCredential"> <message clientCredentialType="UserName"/> </security></span> </binding> </basicHttpBinding> </bindings> <behaviors> <serviceBehaviors> <behavior name="TestServiceBehavior"> <serviceCredentials> <span style='color: blue; font-weight: bold'> <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="UserNamePasswordAuth.DatabaseBasedValidator, UserNamePasswordAuth"/></span> </serviceCredentials> <serviceMetadata httpGetEnabled="true" /> <serviceDebug includeExceptionDetailInFaults="false" /> </behavior> </serviceBehaviors> </behaviors> <serviceHostingEnvironment multipleSiteBindingsEnabled="true" /> </system.serviceModel> </pre> <br /> 일단, 서버 측은 이것으로 완료되었습니다. IIS 서버에 배포하고 HTTPS 바인딩 설정과 자가 서명한 "SSL 인증서"도 할당해 줍니다.<br /> <br /> <img alt='basicHttpBinding_Custom_Auth_1.png' src='/SysWebRes/bbs/basicHttpBinding_Custom_Auth_1.png' /><br /> <br /> 자, 이제 클라이언트 측 호출 코드인데요. 우선, 우리가 임의로 발급한 인증서이기 때문에 이에 대한 유효성 검사를 무시할 수 있도록 다음과 같은 코드를 넣어둡니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > System.Net.ServicePointManager.ServerCertificateValidationCallback = ((sender, certificate, chain, sslPolicyErrors) => true); </pre> <br /> "<a target='tab' href='http://www.sysnet.pe.kr/2/0/864'>WCF 사용자 정의 인증 구현 예제</a>"에서는 serviceCertificate를 자체적으로 지정하고 있었고 클라이언트 측에서는 역시 인증서에 대한 유효성 검사를 <authentication certificateValidationMode="None" /> 설정으로 무시를 했었는데요. HTTPS에 사용된 인증서의 유효성 검사에 대해서는 위와 같이 ServerCertificateValidationCallback을 재지정함으로써 가능합니다.<br /> <br /> 이후 코드는 예전의 것과 다르지 않습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > using (ChannelFactory<WebApplication1.ITestService> factory = new ChannelFactory<WebApplication1.ITestService>("<span style='color: blue; font-weight: bold'>BasicHttpBinding_ITestService</span>")) { factory.Credentials.UserName.UserName = "test"; factory.Credentials.UserName.Password = "test"; WebApplication1.ITestService svc = factory.CreateChannel(); ICommunicationObject cn = svc as ICommunicationObject; try { svc.DoWork(); cn.Close(); } catch (Exception ex) { Console.WriteLine(ex.ToString()); cn.Abort(); } } </pre> <br /> 단지, "BasicHttpBinding_ITestService"로 지정한 app.config의 바인딩 설정만을 맞춰주면 되는데, 다음과 같이 security 노드의 일부 값과 address 값의 https 프로토콜을 사용하도록 변경합니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > <system.serviceModel> <client> <endpoint address="<span style='color: blue; font-weight: bold'>https://...:4430/TestService.svc</span>" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_ITestService" contract="WebApplication1.ITestService" name="BasicHttpBinding_ITestService"/> </client> <bindings> <basicHttpBinding> <binding name="BasicHttpBinding_ITestService"> <span style='color: blue; font-weight: bold'><security mode="TransportWithMessageCredential"> <message clientCredentialType="UserName"/> </security></span> </binding> </basicHttpBinding> </bindings> </system.serviceModel> </pre> <br /> 이제, 실행하면 정상적으로 "test" / "test" 계정으로 인증되는 것을 확인할 수 있습니다.<br /> <br /> <a target='tab' href='http://www.sysnet.pe.kr/bbs/DownloadAttachment.aspx?wid=1082&boardid=331301885'>첨부한 파일</a>은 위의 내용을 포함하고 있습니다.<br /> <br /> <hr style='width: 50%' /><br /> <br /> 그런데, 원래 제가 이번 실습을 하려는 의도는 따로 있었습니다. 바로 아래의 글이 모델이었는데요.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Finally! Usernames over Transport Authentication in WCF ; <a target='tab' href='http://www.leastprivilege.com/PermaLink.aspx?guid=b0ed39eb-01d9-4711-8d38-92d932e2e8c3'>http://www.leastprivilege.com/PermaLink.aspx?guid=b0ed39eb-01d9-4711-8d38-92d932e2e8c3</a> </pre> <br /> 위의 글에서 다음과 같은 문구가 나오는데요.<br /> <br /> <div style='BACKGROUND-COLOR: #ccffcc; padding: 10px 10px 5px 10px; MARGIN: 0px 10px 10px 10px; FONT-FAMILY: Malgun Gothic, Consolas, Verdana; COLOR: #005555'> You may say now - isn't that exactly what TransportWithMessageCredential is supposed to do? Not exactly - because this involves sending a basic WS-Security SOAP header inside of the message. I want simple HTTP basic auth....<br /> </div><br /> <br /> 언급된 것처럼, 다른 플랫폼과의 보다 자유로운 Interop이 이뤄지려면 SecurityMode == TransportWithMessageCredential 상태는 바람직하지 않습니다. 그래서 위의 글에서 설명한 대로 예제를 진행했었는데, (아울러, IIS 서버 측의 "Basic Authentication"을 활성화 시켜야 합니다.)<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > <bindings> <basicHttpBinding> <binding name="secureBasic"> <span style='color: blue; font-weight: bold'><security mode="Transport"> <transport clientCredentialType="Basic" /> </security></span> </binding> </basicHttpBinding> </bindings> </pre> <br /> 아쉽게도, 제 경우에는 customUserNamePasswordValidatorType에 지정된 사용자 정의 인증 모듈이 불려지지 않아서 다음과 같은 오류만 발생했습니다.<br /> <br /> <div style='BACKGROUND-COLOR: #ccffcc; padding: 10px 10px 5px 10px; MARGIN: 0px 10px 10px 10px; FONT-FAMILY: Malgun Gothic, Consolas, Verdana; COLOR: #005555'> System.ServiceModel.Security.MessageSecurityException: The HTTP request is unauthorized with client authentication scheme 'Basic'. The authentication header received from the server was 'Basic realm="..."'. ---> System.Net.WebException: <span style='color: blue; font-weight: bold'>The remote server returned an error: (401) Unauthorized.</span> </div><br /> <br /> 대신에, 지정된 대로 순수하게 Windows에 등록된 계정 정보를 Basic 인증에 넣어서 보내야만 정상적으로 인증이 되었습니다.<br /> <br /> 혹시, basicHttpBinding + security mode="Transport" + clientCredentialType="Basic"의 설정으로 사용자 정의 인증 모듈 호출에 성공하신 분이 있다면 소개 부탁드리겠습니다. ^^<br /> </p><br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
6605
(왼쪽의 숫자를 입력해야 합니다.)