Я пытаюсь реализовать "своего рода" безопасность сервера-клиента и нулевой конфигурации для некоторого сервиса WCF.
Лучшее (и самое простое для меня) решение, которое я нашел на www, это решение, описанное в http://www.dotnetjack.com/post/Automate-passing-valuable-information-in-WCF-headers.aspx (на стороне клиента) и http://www.dotnetjack.com/post/Processing-custom-WCF-header-values-at-server-side.aspx (на стороне сервера).
Ниже моя реализация RequestAuth (описана в первой ссылке выше):
using System;
using System.Diagnostics;
using System.ServiceModel;
using System.ServiceModel.Configuration;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Description;
using System.ServiceModel.Channels;
namespace AuthLibrary
{
/// <summary>
/// Ref: http://www.dotnetjack.com/post/Automate-passing-valuable-information-in-WCF-headers.aspx
/// </summary>
public class RequestAuth : BehaviorExtensionElement, IClientMessageInspector, IEndpointBehavior
{
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private string headerName = "AuthKey";
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private string headerNamespace = "http://some.url";
public override Type BehaviorType
{
get { return typeof(RequestAuth); }
}
protected override object CreateBehavior()
{
return new RequestAuth();
}
#region IClientMessageInspector Members
// Keeping in mind that I am SENDING something to the server,
// I only need to implement the BeforeSendRequest method
public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
{
throw new NotImplementedException();
}
public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel)
{
MessageHeader<string> header = new MessageHeader<string>();
header.Actor = "Anyone";
header.Content = "TopSecretKey";
//Creating an untyped header to add to the WCF context
MessageHeader unTypedHeader = header.GetUntypedHeader(headerName, headerNamespace);
//Add the header to the current request
request.Headers.Add(unTypedHeader);
return null;
}
#endregion
#region IEndpointBehavior Members
public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
{
throw new NotImplementedException();
}
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
clientRuntime.MessageInspectors.Add(this);
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
throw new NotImplementedException();
}
public void Validate(ServiceEndpoint endpoint)
{
throw new NotImplementedException();
}
#endregion
}
}
Итак, сначала я поместил этот код в мое клиентское приложение WinForms, но затем у меня возникли проблемы с его подписанием, потому что мне пришлось подписать также все сторонние ссылки, хотя http://msdn.microsoft.com/en-us/library/h4fa028b(v=VS.80).aspx в разделе «Что не должно быть сильным» Именованные "состояния:
В общем, вам следует избегать сборок EXE приложений с сильными именами. Приложение со строгим именем или компонент не может ссылаться на компонент со слабым именем, поэтому строгое имя EXE-файла не позволяет EXE-файлам ссылаться на библиотеки DLL со слабым именем, которые развернуты вместе с приложением.
По этой причине система проектов Visual Studio не использует EXE-файлы приложений со строгим именем. Вместо этого он строго называет манифест приложения, который внутренне указывает на приложение со слабым именем EXE.
Я ожидал, что VS избежит этой проблемы, но мне не повезло, он пожаловался на все неподписанные ссылки, поэтому я создал в своем проекте отдельный проект "Библиотека сервисов WCF", содержащий только приведенный выше код, и подписал его.
На данный момент все решение скомпилировано просто нормально.
И вот моя проблема:
Когда я запустил «Редактор конфигурации служб WCF», я смог добавить новое расширение элемента поведения (скажем, «AuthExtension»), но затем, когда я попытался добавить это расширение к поведению моей конечной точки, это дает мне:
Исключение было сгенерировано целью вызова.
Так что я застрял здесь.
Есть идеи?