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)
13517정성태1/8/20242221스크립트: 63. Python - 공개 패키지를 이용한 위성 이미지 생성 (pystac_client, odc.stac)
13516정성태1/7/20242347닷넷: 2196. IIS - AppPool의 "Disable Overlapped Recycle" 옵션의 부작용
13515정성태1/6/20242626닷넷: 2195. async 메서드 내에서 C# 7의 discard 구문 활용 사례 [1]
13514정성태1/5/20242319개발 환경 구성: 702. IIS - AppPool의 "Disable Overlapped Recycle" 옵션
13513정성태1/5/20242227닷넷: 2194. C# - WebActivatorEx / System.Web의 PreApplicationStartMethod 특성
13512정성태1/4/20242181개발 환경 구성: 701. IIS - w3wp.exe 프로세스의 ASP.NET 런타임을 항상 Warmup 모드로 유지하는 preload Enabled 설정
13511정성태1/4/20242200닷넷: 2193. C# - ASP.NET Web Application + OpenAPI(Swashbuckle) 스펙 제공
13510정성태1/3/20242122닷넷: 2192. C# - 특정 실행 파일이 있는지 확인하는 방법 (Linux)
13509정성태1/3/20242170오류 유형: 887. .NET Core 2 이하의 프로젝트에서 System.Runtime.CompilerServices.Unsafe doesn't support netcoreapp2.0.
13508정성태1/3/20242243오류 유형: 886. ORA-28000: the account is locked
13507정성태1/2/20242896닷넷: 2191. C# - IPGlobalProperties를 이용해 netstat처럼 사용 중인 Socket 목록 구하는 방법파일 다운로드1
13506정성태12/29/20232483닷넷: 2190. C# - 닷넷 코어/5+에서 달라지는 System.Text.Encoding 지원
13505정성태12/27/20233009닷넷: 2189. C# - WebSocket 클라이언트를 닷넷으로 구현하는 예제 (System.Net.WebSockets)파일 다운로드1
13504정성태12/27/20232591닷넷: 2188. C# - ASP.NET Core SignalR로 구현하는 채팅 서비스 예제파일 다운로드1
13503정성태12/27/20232453Linux: 67. WSL 환경 + mlocate(locate) 도구의 /mnt 디렉터리 검색 문제
13502정성태12/26/20232575닷넷: 2187. C# - 다른 프로세스의 환경변수 읽는 예제파일 다운로드1
13501정성태12/25/20232329개발 환경 구성: 700. WSL + uwsgi - IPv6로 바인딩하는 방법
13500정성태12/24/20232422디버깅 기술: 194. Windbg - x64 가상 주소를 물리 주소로 변환
13498정성태12/23/20233114닷넷: 2186. 한국투자증권 KIS Developers OpenAPI의 C# 래퍼 버전 - eFriendOpenAPI NuGet 패키지
13497정성태12/22/20232509오류 유형: 885. Visual Studiio - error : Could not connect to the remote system. Please verify your connection settings, and that your machine is on the network and reachable.
13496정성태12/21/20232506Linux: 66. 리눅스 - 실행 중인 프로세스 내부의 환경변수 설정을 구하는 방법 (gdb)
13495정성태12/20/20232433Linux: 65. clang++로 공유 라이브러리의 -static 옵션 빌드가 가능할까요?
13494정성태12/20/20232612Linux: 64. Linux 응용 프로그램의 (C++) so 의존성 줄이기(ReleaseMinDependency) - 두 번째 이야기
13493정성태12/19/20232759닷넷: 2185. C# - object를 QueryString으로 직렬화하는 방법
13492정성태12/19/20232428개발 환경 구성: 699. WSL에 nopCommerce 예제 구성
13491정성태12/19/20232282Linux: 63. 리눅스 - 다중 그룹 또는 사용자를 리소스에 권한 부여
1  2  3  4  [5]  6  7  8  9  10  11  12  13  14  15  ...