.NET 1.1 WSDL — невозможно использовать IntPtr (WindowsIdentity.Token) в качестве входного параметра в WebMethod (веб-служба ASMX)

Мы находимся в странной ситуации с устаревшим приложением winforms VB.NET 1.1, использующим веб-службы ASMX. Попытка отправить токен пользователя из объекта WindowsIdentity в качестве параметра в WebMethod. Я добавлю комментарий «HACK:».

System.Security.Principal.WindowsIdentity.GetCurrent().Token

Маркер имеет тип IntPtr, первая проблема заключается в том, что создаваемый WSDL не поддерживает IntPtr с ошибкой «неподдерживаемый тип».

Я знаю, что это большой вопрос WTF и звучит небезопасно, поэтому приветствуются любые простые полезные альтернативы, но есть много ограничений на то, как мы можем изменить эту систему, включая сложности со средой хостинга. Поэтому я просто хотел бы передать наш фрагмент данных в веб-службу, чтобы избавить от многих других головных болей.

Проблема 1

Ошибка генерации WSDL:

Method userClass.TestSendIntPtr can not be reflected. 
--> There was an error reflecting 'token'. 
--> System.IntPtr is an unsupported type.

Альтернативный подход (расширяющий фактор WTF) - попытка обойти проблему IntPtr заключается в том, чтобы просто поместить IntPtr в System.IO.Stream, используя

BinaryFormatter.Serialize()

в конце приложения winforms и BF.Deserialize() в службе. Но это приводит к новой странной проблеме.

Определение подписи метода веб-службы следующим образом:

Public Class UserService
    Inherits System.Web.Services.WebService

    <WebMethod()> _
    Public Function UserToken(ByVal tokenStream As System.IO.Stream) As Boolean

Новая странная проблема возникает на стороне клиента как ошибка компиляции, как будто квалификация Stream «System.IO» игнорируется и интерпретируется как часть класса UserService...

Проблема 2

Value of type 'System.IO.Stream' cannot be converted to 'USERSERVICE.Stream'.

Так что ответ на любой вопрос или аналогичный альтернативный подход был бы замечательным...


person Nick Josevski    schedule 26.06.2009    source источник
comment
Если бы мы использовали только WCF, это не было бы проблемой, но это всего лишь патч для устаревшей системы, без каких-либо существенных улучшений.   -  person Nick Josevski    schedule 26.06.2009


Ответы (1)


Если IntPtr не работает из-за отсутствия поддержки в WSDL, используйте вместо него Long. IntPtr могут быть преобразованы в типы Integer и Long и обратно. Вы можете просто передать значение как один из этих типов (предпочтительно Long) и преобразовать его обратно на другом конце.

Преобразовать в длинный

Dim value As Long = token.ToInt64()

Конвертировать из длинного

Dim token as IntPtr = new IntPtr(value)

Одна вещь, которую вы должны отметить, заключается в том, что токен действителен только в адресном пространстве процесса, создавшего значение. Если вы передаете значение через веб-службу, которая находится в другом процессе, токен не будет иметь доказательной ценности. У него будет тот же физический адрес, но вы не сможете запрашивать значения для этого токена.

person JaredPar    schedule 26.06.2009
comment
Спасибо JaredPar, отправка токена бесполезна. Была предпринята попытка воссоздать WindowsIdentity в службе. Только из-за других трудностей, не позволяющих нам подключиться к веб-службе, которая правильно настроена для встроенной безопасности. Воссоздавать это неразумно/практично/достижимо. Спасибо, что нашли время дать ответ, подтверждающий, почему это неправильный подход. - person Nick Josevski; 29.06.2009
comment
Я знаю, что это старый вопрос, но я как-то в похожей ситуации, только все мои «операции» происходят на одной машине. Мне нужно создать во время входа в систему IntPtr, указывающий на токен WindowsIdenity. Моя первоначальная мысль состоит в том, чтобы «сохранить» этот IntPtr в токене OAuth, чтобы в последующих вызовах я мог олицетворять этого пользователя, создавая WindowsIdentity с помощью IntPtr. Будет ли это по-прежнему жизнеспособным решением, учитывая, что все происходит на одной машине? Спасибо. - person Pepito Fernandez; 21.01.2016