У меня есть требование для защиты потоковой конечной точки службы WCF net.tcp с помощью WIF . Он должен аутентифицировать входящие звонки на наш токен-сервер. Служба потоковая, потому что она предназначена для передачи больших объемов данных и прочего.
Это кажется невозможным. И если я не смогу обойти добычу, мое Рождество испортится, и я буду пить до смерти в канаве, пока веселые покупатели переступают через мое медленно остывающее тело. Серьезные слова, ребята.
Почему это невозможно? Вот Поймай-22.
На клиенте мне нужно создать канал с GenericXmlSecurityToken, который я получаю от нашего токен-сервера. Без проблем.
// people around here hate the Framework Design Guidelines.
var token = Authentication.Current._Token;
var service = base.ChannelFactory.CreateChannelWithIssuedToken(token);
return service.Derp();
Я сказал "нет проблем"? Problemo. На самом деле, NullReferenceException
стиль проблемный.
«Братан, - спросил я Фреймворк, - ты вообще проверил ноль?» Фреймворк молчал, поэтому я разобрал и обнаружил, что
((IChannel)(object)tChannel).
GetProperty<ChannelParameterCollection>().
Add(federatedClientCredentialsParameter);
был источником исключения, и что GetProperty
звонок возвращался null
. Итак, WTF? Оказывается, что если я включу безопасность сообщений и установлю тип учетных данных клиента, IssuedToken
то это свойство теперь существует в ClientFactory
(protip: в IChannel, ублюдок, нет эквивалента "SetProperty").
<binding name="OMGWTFLOL22" transferMode="Streamed" >
<security mode="Message">
<message clientCredentialType="IssuedToken"/>
</security>
</binding>
Сладкий. Нет больше NRE. Однако, теперь мой клиент виноват при рождении (все еще люблю его, хотя). Копаясь в диагностике WCF (прототип: заставьте своих злейших врагов делать это после того, как сокрушите их и гоните их перед вами, но прямо перед тем, как получить удовольствие от жалоб своих женщин и детей), я вижу, что это из-за несоответствия безопасности между сервером и клиентом.
Запрошенное обновление не поддерживается net.tcp: // localhost: 49627 / MyService. Это может быть связано с несовпадающими привязками (например, защита включена на клиенте, а не на сервере).
Проверяя настройки хоста (снова: раздавить, загнать, почитать логи, насладиться причитаниями), я вижу, что это правда
Тип протокола application / ssl-tls был отправлен службе, которая не поддерживает этот тип обновления.
«Ну что ж, - говорит я, - я просто включу безопасность сообщений на хосте!» И я делаю. Если вы хотите знать, как это выглядит, это точная копия конфигурации клиента. Уважать.
Результат: Kaboom.
Привязка ('NetTcpBinding', ' http://tempuri.org/ ') поддерживает потоковую передачу, которую нельзя настроить вместе с безопасностью на уровне сообщений. Подумайте о выборе другого режима передачи или безопасности на транспортном уровне.
Таким образом, мой хост не может быть как потоковым, так и защищенным с помощью токенов . Словить 22.
tl; dr: Как я могу защитить потоковую конечную точку WCF net.tcp, используя WIF ???
<security mode="Transport" /> <transport clientCredentialType="IssuedToken" /> </security>
TransportWithMessageCredential
Режим может быть другой вариант.Ответы:
В WCF есть несколько проблем с потоковой передачей (я смотрю на вас, MTOM 1 ) из-за фундаментальной проблемы того, как он не может выполнить предварительную аутентификацию, как большинство людей считает, что это должно работать (это влияет только на последующие запросы для этого канала , не первый запрос) Хорошо, так что это не совсем ваша проблема, но, пожалуйста, следуйте, как я доберусь до вашего в конце. Обычно HTTP-вызов работает так:
Теперь, если вы когда-нибудь попытаетесь включить потоковую передачу MTOM на конечной точке WCF на сервере, он не будет жаловаться. Но, когда вы настраиваете его на клиентском прокси-сервере (как и должно быть, они должны соответствовать привязкам), он взорвется пламенной смертью. Причина этого заключается в том, что приведенная выше последовательность событий, которую WCF пытается предотвратить, заключается в следующем:
Обратите внимание, что вы только что отправили 200 МБ на сервер, когда вам нужно было только отправить 100 МБ. Ну, это проблема. Ответ заключается в отправке аутентификации с первой попытки, но это невозможно в WCF без написания пользовательского поведения. Во всяком случае, я отвлекся.
Твоя проблема
Прежде всего, позвольте мне сказать вам, что то, что вы пытаетесь, невозможно 2 . Теперь, чтобы вы перестали вращать свои колеса, позвольте мне сказать вам, почему:
Меня поражает, что вы сейчас блуждаете в подобном классе проблем. Если вы включите защиту на уровне сообщений, клиент должен загрузить весь поток данных в память, прежде чем он сможет фактически закрыть сообщение с помощью обычной хеш-функции и XML-подписи, требуемой ws-security. Если он должен прочитать весь поток, чтобы подписать одно сообщение (которое на самом деле не является сообщением, но это один непрерывный поток), тогда вы можете увидеть проблему здесь. WCF должен будет один раз передать его «локально», чтобы вычислить безопасность сообщения, а затем снова передать его, чтобы отправить на сервер. Это явно глупо, поэтому WCF не разрешает безопасность на уровне сообщений для потоковой передачи данных.
Итак, простой ответ здесь заключается в том, что вы должны отправить токен либо в качестве параметра в исходный веб-сервис, либо в виде заголовка SOAP и использовать пользовательское поведение для его проверки. Вы не можете использовать WS-Security для этого. Честно говоря, это не просто проблема WCF - я не вижу, как это могло бы работать практически для любых других стеков.
Решение проблемы MTOM
Это только для примера, как я решил мою проблему потоковой передачи MTOM для базовой аутентификации, так что, возможно, вы могли бы взять на себя смелость этого и реализовать нечто подобное для вашей проблемы. Суть в том, что для того, чтобы включить свой собственный инспектор сообщений, вы должны отключить все понятия безопасности на клиентском прокси (он остается включенным на сервере), кроме транспортного уровня (SSL):
Обратите внимание, что я отключил транспортную безопасность здесь, потому что я сам буду обеспечивать это с помощью инспектора сообщений и пользовательского поведения:
Таким образом, этот пример предназначен для всех, кто страдает проблемой MTOM, но также в качестве каркаса для реализации чего-то подобного для аутентификации вашего токена, сгенерированного первичной службой токенов с защитой WIF.
Надеюсь это поможет.
(1) Большие данные и потоковая передача
(2) Безопасность сообщений в WCF (см. «Недостатки».)
источник
MTOM and Basic Authorization
а MTOM и OAuth2 ?