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)
13981정성태8/1/2025170오류 유형: 971. CentOS 7에서 yum 사용 시 "Could not resolve host: mirrorlist.centos.org; Unknown error"
13980정성태7/31/2025244Linux: 119. eBPF - BPF_PROG_TYPE_CGROUP_SOCK 유형에서 정상 동작하지 않는 BPF_CORE_READ (2)
13979정성태7/30/2025272Linux: 118. eBPF - BPF_PROG_TYPE_CGROUP_SOCK 유형에서 정상 동작하지 않는 BPF_CORE_READ
13978정성태7/29/2025365오류 유형: 970. 파일 복사 시 "Data error (cyclic redundancy check). (0x80070017)" 에러
13977정성태7/28/2025484닷넷: 2349. C# 14 - (5) 문자열 리터럴을 utf-8 인코딩으로 저장파일 다운로드1
13976정성태7/25/2025719닷넷: 2348. C# - 카카오 카나나 모델 + Microsoft.ML.OnnxRuntimeGenAI 예제파일 다운로드1
13975정성태7/23/2025845닷넷: 2347. C# 14 - (4) 형식 인자가 없는 제네릭 타입의 nameof 지원파일 다운로드1
13974정성태7/22/20251119닷넷: 2346. C# 14 - (3) Span 타입과 배열 간의 암시적 형변환파일 다운로드1
13973정성태7/21/20251023닷넷: 2345. C# - 배열 및 Span의 공변성파일 다운로드1
13972정성태7/21/20251291닷넷: 2344. C#의 Identity conversion 의미파일 다운로드1
13971정성태7/17/20251428닷넷: 2343. C# 14 - (2) 속성 구문에서 문맥 키워드로 추가되는 field 예약어파일 다운로드1
13970정성태7/17/20251387닷넷: 2342. C# 14 - (1) (예약)
13969정성태7/17/20251434닷넷: 2341. snap으로 설치한 .NET 리눅스 실행 환경
13968정성태7/16/20251314오류 유형: 969. lddtree - TypeError: 'type' object is not subscriptable
13967정성태7/16/20251835오류 유형: 968. snap으로 설치한 "dotnet run" 실행 시 "undefined symbol: _dl_audit_symbind_alt, version GLIBC_PRIVATE" 오류
13966정성태7/15/20252380디버깅 기술: 223. WinDbg - .kframes 명령어
13965정성태7/11/20251661오류 유형: 967. 디버깅 모드로 실행 시 "Could not find file 'C:\Program Files\IIS Express\Oracle.DataAccess.Common.Configuration.Section.xsd'" 예외
13964정성태7/10/20252331닷넷: 2340. C# - Win32 Multimedia Timer 주기파일 다운로드1
13963정성태7/8/20251876VS.NET IDE: 202. Visual Studio 2022 + Copilot 기본 사용법
13962정성태7/7/20251896스크립트: 79. 파이썬 - onnxruntime_genai에서 지원하지 않는 모델 사용
13961정성태7/5/20251600디버깅 기술: 222. WinDbg 분석 사례 - IISreset 시점에 w3wp.exe의 crash 발생
13960정성태7/3/20252786개발 환경 구성: 752. ProcDump - C/C++ 예외 코드 필터를 지정한 덤프 생성 [2]
13959정성태6/25/20251813오류 유형: 966. Ubuntu - ping: connect: Network is unreachable
13958정성태6/21/20252470닷넷: 2339. C# - Phi-4-multimodal 모델의 GPU 가속 방법 (ORT 사용)파일 다운로드1
13957정성태6/20/20252915닷넷: 2338. C# / Foundry Local - Phi-4-multimodal 모델을 사용하는 방법 [1]
[1]  2  3  4  5  6  7  8  9  10  11  12  13  14  15  ...