WCF Custom JSONP Binding и httpsTransport
Мой вопрос вращается вокруг службы WCF REST для IIS, которая отвечает JSONP. Я взял классы в этом решении: http://msdn.microsoft.com/en-us/library/cc716898.aspx и добавил их к моему. Все отлично работало на моей рабочей станции разработчика, используя олицетворение с помощью httpTransport, но когда я попытался перейти на сервер разработки, я столкнулся с некоторыми проблемами безопасности. Эти проблемы были решены с использованием следующей конфигурации и пользователя идентификации пула приложений. Я также настраиваю файл метабазы IIS для проверки подлинности только NTLM (мы используем IIS 6, но скоро будем работать с IIS 7, нужно работать на обоих), поскольку у меня нет доступа к созданию SPN. Я считаю, что текущая конфигурация решила мои проблемы безопасности , но в процессе мой ответ JSONP был понижен до версии JSON, это проблема. Вот соответствующая конфигурация:
<services>
<service name="IS.Core.Infrastructure.RESTRouter.Transactions" behaviorConfiguration="">
<endpoint address="" behaviorConfiguration="webHttp" binding="customBinding"
bindingConfiguration="jsonpBinding" contract="IS.Core.Infrastructure.RESTRouter.ITransactions">
</endpoint>
</service>
<service name="IS.Core.Infrastructure.RESTRouter.Queue" behaviorConfiguration="">
<endpoint address="" behaviorConfiguration="webHttp" binding="customBinding"
bindingConfiguration="jsonpBinding" contract="IS.Core.Infrastructure.RESTRouter.IQueue" />
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="webHttp">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<customBinding>
<binding name="jsonpBinding">
<jsonpMessageEncoding />
<httpsTransport
manualAddressing="true"
authenticationScheme="Ntlm" />
</binding>
</customBinding>
</bindings>
<extensions>
<bindingElementExtensions>
<add name="jsonpMessageEncoding"
type="IS.Core.Infrastructure.RESTRouter.JsonpBindingExtension, RESTRouter, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</bindingElementExtensions>
</extensions>
Вот одно из определений метода интерфейса:
[OperationContract]
[WebGet(UriTemplate = "{ModelPath}/{ObjectTypeName}?callback={callback}", ResponseFormat = WebMessageFormat.Json)]
[JSONPBehavior(callback = "callback")]
JSONPXml NewObject(string ModelPath, string ObjectTypeName, string callback);
Вот его реализация:
[OperationBehavior(Impersonation = ImpersonationOption.Allowed)]
public JSONPXml NewObject(string ModelPath, string ObjectTypeName, string callback) {
int val = getEmployeeIdByNTUsername(OperationContext.Current.ServiceSecurityContext.PrimaryIdentity.Name);
JSONPXml jsp = null;
EntityPluginReflectorClient client = null;
try {
client = new EntityPluginReflectorClient();
string output = client.NewObject(ModelPath, ObjectTypeName);
jsp = new JSONPXml() { xml = output };
} catch (Exception e) {
InfrastructureLog.WriteException(this, "NewObject", e);
jsp = getExceptionResponse(e);
}
finally {
client.Close();
}
return (jsp);
}
и вот контракт с данными:
[DataContract()]
public class JSONPXml {
public JSONPXml() { }
[DataMember]
public string xml;
}
Пожалуйста, дайте мне знать, нужна ли дополнительная информация и спасибо за изучение этого.
Ответы
Ответ 1
Я не уверен на 100% ответа, но вот несколько вещей, которые помогут вам сузить его:
Для начала, если вы установите ProtectionLevel явно в Sign Signed или EncryptAndSign, тогда вы должны использовать привязку с включенной безопасностью или исключение будут выброшены. Это начнет бросать исключения, если вы попытаетесь получить доступ к нему через http, что поможет вам понять, как вы на самом деле обращаетесь к службе.
Во-вторых, поскольку вы используете customBinding, вам нужно указать, какой тип безопасности вы хотите в привязке. Я не думаю, что этого достаточно, чтобы просто указать httpsTransport
. Как вы это делаете, с помощью тега безопасности. По его звуку вам нужно будет установить authenticationMode="SspiNegotiated"
.
В соответствии с пользовательскими документами привязки
Порядок, в котором элементы появляются в стек имеет значение, потому что это порядок, в котором применяются операции к сообщению. Рекомендуемый заказ элементов стека:
Транзакции (необязательно)
Надежная передача сообщений (необязательно)
Безопасность (необязательно)
Транспорт
Кодировщик (необязательно)
Дополнительная информация о пользовательской привязке здесь и здесь
Надеюсь, это поможет.
Ответ 2
Это может показаться очевидным, но проверили ли вы, что вы все еще передаете параметр запроса "обратный вызов" на сервере разработки?
Глядя на источник JSONPEncoder, кажется, он все равно будет писать сообщение JSON для ответа, даже если параметр "обратный вызов" не был получен. Он просто не будет форматировать оболочку JavaScript-метода.