Microsoft MVP성태의 닷넷 이야기
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 
(연관된 글이 1개 있습니다.)

서버 측 SoapExtension을 클라이언트에 알리고 싶다.


언제나, 제목 짓기가 정말 힘들군요. 휴...

우선, 오늘의 이야기는 기본적으로 SoapExtension을 알고 있다는 가정하에 진행합니다. 행여나 모르시는 분들이 계시다면 다음의 토픽을 참조하시면 잘 아실 수 있을 테니... 굳이 여기서 또다시 설명하진 않겠습니다. ^^

Soap 익스텐션(SoapExtension)을 고한다.
; http://dalbong2.net/130

한때, WSE, WCF 등의 기술이 나오지 않았을 때는, ASP.NET의 asmx를 확장하기 위해서 심심치 않게 고려되곤 했던 기술인데... 최근에도 그런지는 잘 모르겠군요.




그런데, SoapExtension에는 한가지 문제가 있습니다. (정확하게 말하면 문제가 있는 "듯"합니다.) 한 번쯤 SoapExtension을 재미 삼아서라도 해보신 분들은 아마도 공감이 가실 텐데요. 바로 클라이언트 측의 코드 제어가 안된다는 점입니다.

가령 예를 들어서, (SoapExtension 구현의 전형적인 예제인) 암호화 SoapExtension을 구현한다고 가정해 보겠습니다. asmx 웹 메서드마다 EncryptionAttribute 특성을 정의해 두고 개별 메서드 단위로 입/출력 인자에 대해서 암호화 유무를 정해주고 싶은 경우가 있을 수 있습니다.

간단한 코드 예를 들어보면.

[코드 1: 메서드 단위로 설정되는 SoapExtension 옵션 값]
// Soap 요청은 암호화 된 것만 받아들이고.
// 출력 Soap 내용은 평문으로 보낸다.
[EncryptionAttribute(Input = true, Output = false)]
public string MyMethod1(string txt)
{
 return txt;
}

// 입력은 암호화 된 것만 받아들이므로 SoapExtension에서 복호화 시키고,
// 출력도 SoapExtension에 의해서 암호화 되어 내려보낸다.
[EncryptionAttribute(Input = true, Output = true)]
public string MyMethod2(string txt)
{
 return txt;
}

사실, 꼭 암호화가 아니더라도 여러분들의 SoapExtension에서 "메서드" 단위로 지정되는 경우가 아마 있었을 것입니다.

물론... 이렇게 하면 문제가 되는 부분이 있죠? 바로 WSDL에 해당 메서드에 대해서 암호화를 필요로 하는지에 대한 여부가 나오지 않는다는 것입니다. 그래서, 클라이언트 측에서 WSDL.exe로 코드를 생성한 다음에 클라이언트 측 메서드마다 일일이 EncryptionAttribute 특성을 지정해 주어야만 했습니다.

아마 여기서 고개를 끄덕끄덕 하시는 분들이 계실 것 같습니다. ^^

그나마 .NET 2.0에서는 partial 클래스가 나온 탓에 SoapExtension이 "클래스" 단위로 영향을 미치게 되는 경우에는 쉽게 해결이 될 수 있지만, "메서드" 단위로 영향을 미치게 되는 경우에는 답이 없습니다. 이런 상황이 되면... 아무리 기술이 좋고 이 방법밖에 없다고 해도 고객은 쉽게 "OK"하지 않을 것입니다. (저 같아도 ... ^^)




SoapExtension은 마이크로소프트에서 ASP.NET asmx에 대해서 제공해주는 "확장"기능입니다. 훌륭하게도, 마이크로소프트는 SoapExtension의 사용으로 인한 WSDL의 확장까지도 제공해 주고 있으니, 그것이 바로 "ServiceDescriptionFormatExtension"이라는 클래스입니다.

예를 먼저 들어보면. "[코드 1]"에서 설명한 문제를 해결하기 위해서는, WSDL에 다음과 같은 식으로 메서드별로 원하는 값을 "분명하게" 명시를 해주면 됩니다.

<operation name="MyMethod1">
	<soap:operation style="document" soapAction="http://tempuri.org/MyMethod1" />
	<enc:encryption Input="true" Output="false" />
	<input>
	<soap:body use="literal" />
	</input>
	<output>
	<soap:body use="literal" />
	</output>
</operation>

<operation name="MyMethod2">
	<soap:operation style="document" soapAction="http://tempuri.org/MyMethod2" />
	<enc:encryption Input="true" Output="true" />
	<input>
	<soap:body use="literal" />
	</input>
	<output>
	<soap:body use="literal" />
	</output>
</operation>

이와 같이 WSDL에 확장 노드를 삽입하기 위해서는, 우선 위의 상황에서 operation 하위에 추가되는 enc:encryption 노드를 표현하는 클래스를 만들어 주어야 합니다.

[XmlFormatExtension ("encryption", "https://www.sysnet.pe.kr/EncTest", typeof (OperationBinding))]
[XmlFormatExtensionPrefix ("enc", "https://www.sysnet.pe.kr/EncTest")]
public class EncryptionOperationBinding : ServiceDescriptionFormatExtension
{
	private bool input;
	private bool output;
	
	[XmlAttribute]
	[DefaultValue (true)]
	public bool Input
	{
		get { return input; }
		set { input = value; }
	}
	
	[XmlAttribute]
	[DefaultValue (true)]
	public bool Output
	{
		get { return output; }
		set { output = value; }
	}	
}

그런 다음 위의 표현을 실제로 WSDL 생성과정에 넣어주는 동작을 해주는 클래스를 정의해야 하는데, 이는 다음과 같이 "SoapExtensionReflector" 클래스에 상속받아서 구현할 수 있습니다.

public class EncryptionExtensionReflector : SoapExtensionReflector
{
	public override void ReflectMethod()
	{
		object[] attrs = 
		  ReflectionContext.Method.MethodInfo.GetCustomAttributes(typeof(EncryptionAttribute), true);
		  
		if (attrs.Length > 0)
		{
			EncryptionAttribute attr = (EncryptionAttribute)attrs[0];
			EncryptionOperationBinding operationBinding = new EncryptionOperationBinding();
			operationBinding.Input = attr.Input;
			operationBinding.Output = attr.Output;
			
			ReflectionContext.OperationBinding.Extensions.Add(operationBinding);
		}
	}
}

일단, 위의 과정으로 모든 구현은 완료가 되었습니다. 이제 EncryptionExtensionReflector, EncryptionOperationBinding 클래스를 WSDL 생성 과정에 참여할 수 있도록 web.config에 다음과 같은 식으로 등록해 주시면 됩니다.

<webServices>
	<serviceDescriptionFormatExtensionTypes>
		<add type="EncryptionOperationBinding, EncryptionSoapExtensions" />
	</serviceDescriptionFormatExtensionTypes>
	
	<soapExtensionReflectorTypes>
		<add type="EncryptionExtensionReflector, EncryptionSoapExtensions" />
	</soapExtensionReflectorTypes>
</webServices>

자, 그럼 모든 설명이 끝이 난 것 같습니다.

음... 그런데, 혹시... 질문 없으세요?

물론입니다. 당연히 질문이 있으셔야 합니다. ^^ 위와 같이 WSDL에 "표시"를 해주었다고 해서 클라이언트 측에서 wsdl.exe에 의해서 자동 생성되는 코드에 Encryption 여부를 지정해주는 코드가 생성될 리 없습니다.

하지만, 위의 질문은 이미 예전에 답변을 해드렸습니다. 이에 대해서는 아래의 토픽을 참고하십시오.

BUG: 웹 서비스에서 DataTable 사용하기 
; https://www.sysnet.pe.kr/2/0/338




[이 토픽에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]

[연관 글]






[최초 등록일: ]
[최종 수정일: 6/28/2021]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 




... 121  122  123  124  125  126  127  128  129  130  131  [132]  133  134  135  ...
NoWriterDateCnt.TitleFile(s)
1788정성태10/22/201424214VC++: 82. COM 프로그래밍에서 HRESULT 타입의 S_FALSE는 실패일까요? 성공일까요? [2]
1787정성태10/22/201432506오류 유형: 252. COM 개체 등록시 0x8002801C 오류가 발생한다면?
1786정성태10/22/201434009디버깅 기술: 65. 프로세스 비정상 종료 시 "Debug Diagnostic Tool"를 이용해 덤프를 남기는 방법 [3]파일 다운로드1
1785정성태10/22/201423094오류 유형: 251. 이벤트 로그 - Load control template file /_controltemplates/TaxonomyPicker.ascx failed [1]
1784정성태10/22/201430667.NET Framework: 472. C/C++과 C# 사이의 메모리 할당/해제 방법파일 다운로드1
1783정성태10/21/201424482VC++: 81. 프로그래밍에서 borrowing의 개념
1782정성태10/21/201421251오류 유형: 250. 이벤트 로그 - Application Server job failed for service instance Microsoft.Office.Server.Search.Administration.SearchServiceInstance
1781정성태10/21/201421971디버깅 기술: 64. new/delete의 짝이 맞는 경우에도 메모리 누수가 발생한다면?
1780정성태10/15/201425798오류 유형: 249. The application-specific permission settings do not grant Local Activation permission for the COM Server application with CLSID
1779정성태10/15/201421004오류 유형: 248. Active Directory에서 OU가 지워지지 않는 경우
1778정성태10/10/201419436오류 유형: 247. The Netlogon service could not create server share C:\Windows\SYSVOL\sysvol\[도메인명]\SCRIPTS.
1777정성태10/10/201422462오류 유형: 246. The processing of Group Policy failed. Windows attempted to read the file \\[도메인]\sysvol\[도메인]\Policies\{...GUID...}\gpt.ini
1776정성태10/10/201419543오류 유형: 245. 이벤트 로그 - Name resolution for the name _ldap._tcp.dc._msdcs.[도메인명]. timed out after none of the configured DNS servers responded.
1775정성태10/9/201420788오류 유형: 244. Visual Studio 디버깅 (2) - Unable to break execution. This process is not currently executing the type of code that you selected to debug.
1774정성태10/9/201427697개발 환경 구성: 246. IIS 작업자 프로세스의 20분 자동 재생(Recycle)을 끄는 방법
1773정성태10/8/201430933.NET Framework: 471. 웹 브라우저로 다운로드가 되는 파일을 왜 C# 코드로 하면 안되는 걸까요? [1]
1772정성태10/3/201419739.NET Framework: 470. C# 3.0의 기본 인자(default parameter)가 .NET 1.1/2.0에서도 실행될까? [3]
1771정성태10/2/201428895개발 환경 구성: 245. 실행된 프로세스(EXE)의 명령행 인자를 확인하고 싶다면 - Sysmon [4]
1770정성태10/2/201422759개발 환경 구성: 244. 매크로 정의를 이용해 파일 하나로 C++과 C#에서 공유하는 방법 [1]파일 다운로드1
1769정성태10/1/201425516개발 환경 구성: 243. Scala 개발 환경 구성(JVM, 닷넷) [1]
1768정성태10/1/201420304개발 환경 구성: 242. 배치 파일에서 Thread.Sleep 효과를 주는 방법 [5]
1767정성태10/1/201425664VS.NET IDE: 94. Visual Studio 2012/2013에서의 매크로 구현 - Visual Commander [2]
1766정성태10/1/201423781개발 환경 구성: 241. 책 "프로그래밍 클로저: Lisp"을 읽고 나서. [1]
1765정성태9/30/201427447.NET Framework: 469. Unity3d에서 transform을 변수에 할당해 사용하는 특별한 이유가 있을까요?
1764정성태9/30/201423694오류 유형: 243. 파일 삭제가 안 되는 경우 - The action can't be comleted because the file is open in System
1763정성태9/30/201425203.NET Framework: 468. PDB 파일을 연동해 소스 코드 라인 정보를 알아내는 방법파일 다운로드1
... 121  122  123  124  125  126  127  128  129  130  131  [132]  133  134  135  ...