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

비밀번호

댓글 작성자
 




[1]  2  3  4  5  6  7  8  9  10  11  12  13  14  15  ...
NoWriterDateCnt.TitleFile(s)
13917정성태4/30/202567VS.NET IDE: 199. Directory.Build.props에 정의한 속성에 대해 Condition 제약으로 값을 변경하는 방법
13916정성태4/23/2025472디버깅 기술: 221. WinDbg 분석 사례 - ASP.NET HttpCookieCollection을 다중 스레드에서 사용할 경우 무한 루프 현상 - 두 번째 이야기
13915정성태4/13/20251685닷넷: 2331. C# - 실행 시에 메서드 가로채기 (.NET 9)파일 다운로드1
13914정성태4/11/20251988디버깅 기술: 220. windbg 분석 사례 - x86 ASP.NET 웹 응용 프로그램의 CPU 100% 현상 (4)
13913정성태4/10/20251215오류 유형: 950. Process Explorer - 64비트 윈도우에서 32비트 프로세스의 덤프를 뜰 때 "Error writing dump file: Access is denied." 오류
13912정성태4/9/2025874닷넷: 2330. C# - 실행 시에 메서드 가로채기 (.NET 5 ~ .NET 8)파일 다운로드1
13911정성태4/8/20251116오류 유형: 949. WinDbg - .NET Core/5+ 응용 프로그램 디버깅 시 sos 확장을 자동으로 로드하지 못하는 문제
13910정성태4/8/20251266디버깅 기술: 219. WinDbg - 명령어 내에서 환경 변수 사용법
13909정성태4/7/20251775닷넷: 2329. C# - 실행 시에 메서드 가로채기 (.NET Framework 4.8)파일 다운로드1
13908정성태4/2/20252184닷넷: 2328. C# - MailKit: SMTP, POP3, IMAP 지원 라이브러리
13907정성태3/29/20251996VS.NET IDE: 198. (OneDrive, Dropbox 등의 공유 디렉터리에 있는) C# 프로젝트의 출력 경로 변경하기
13906정성태3/27/20252270닷넷: 2327. C# - 초기화되지 않은 메모리에 접근하는 버그?파일 다운로드1
13905정성태3/26/20252308Windows: 281. C++ - Windows / Critical Section의 안정화를 위해 도입된 "Keyed Event"파일 다운로드1
13904정성태3/25/20251916디버깅 기술: 218. Windbg로 살펴보는 Win32 Critical Section파일 다운로드1
13903정성태3/24/20251536VS.NET IDE: 197. (OneDrive, Dropbox 등의 공유 디렉터리에 있는) C++ 프로젝트의 출력 경로 변경하기
13902정성태3/24/20251748개발 환경 구성: 742. Oracle - 테스트용 hr 계정 및 데이터 생성파일 다운로드1
13901정성태3/9/20252138Windows: 280. Hyper-V의 3가지 Thread Scheduler (Classic, Core, Root)
13900정성태3/8/20252362스크립트: 72. 파이썬 - SQLAlchemy + oracledb 연동
13899정성태3/7/20251835스크립트: 71. 파이썬 - asyncio의 ContextVar 전달
13898정성태3/5/20252158오류 유형: 948. Visual Studio - Proxy Authentication Required: dotnetfeed.blob.core.windows.net
13897정성태3/5/20252389닷넷: 2326. C# - PowerShell과 연동하는 방법 (두 번째 이야기)파일 다운로드1
13896정성태3/5/20252204Windows: 279. Hyper-V Manager - VM 목록의 CPU Usage 항목이 항상 0%로 나오는 문제
13895정성태3/4/20252248Linux: 117. eBPF / bpf2go - Map에 추가된 요소의 개수를 확인하는 방법
13894정성태2/28/20252287Linux: 116. eBPF / bpf2go - BTF Style Maps 정의 구문과 데이터 정렬 문제
13893정성태2/27/20252225Linux: 115. eBPF (bpf2go) - ARRAY / HASH map 기본 사용법
[1]  2  3  4  5  6  7  8  9  10  11  12  13  14  15  ...