У меня есть метод GetColors
, который принимает GetColorIdsRQ
в качестве параметра и возвращает GetColorIdsRS
. GetColorIdsRQ
- это SOAP-запрос, а GetColorIdsRS
- это SOAP-Resposne. Вот детали реализации каждого из них:
GetColorIdsRQ:
[DataContract]
public class GetColorIdsRQ
{
[DataMember(Name="UserCredentials",Order=0,IsRequired=true)]
public UserCredentials UserCredentials { get; set; }
}
UserCredentials:
[DataContract(Name="UserCredentials")]
public class UserCredentials
{
[DataMember(Name="Username",Order=0,IsRequired=true)]
public string UserName { get; set; }
[DataMember(Name="Password",Order=1,IsRequired=true)]
public string Password { get; set; }
}
GetColorIdsRS:
[DataContract]
public class GetColorIdsRS
{
[DataMember(Name = "ColorsIds", IsRequired = true, Order = 0)]
public List<Color> ColorIds { get; set; }
}
Цвет:
[DataContract(Name="Color")]
public class Color
{
[DataMember(Name="Code",IsRequired=true,Order=0)]
public string Code { get; set; }
[DataMember(Name="Name",IsRequired=true,Order=1)]
public string Name { get; set; }
}
Вот как метод является объявлением в интерфейсе:
[OperationContract(Name = "GetColorIds")]
GetColorIdsRS GetColorsIds(GetColorIdsRQ req);
Это реализация GetColorIds:
public GetColorIdsRS GetColors(GetColorIdsRQ req)
{
GetColorIdsRS getColorIdsRS = new GetColorIdsRS();
List<Color> colorIds = new List<Color>();
req.UserCredentials.UserName = "test";
req.UserCredentials.Password = "test";
//Validate Username and Password
DataTable dtColorIds = Data.GetDataTable("GetColors");
foreach (DataRow item in dtColorIds.Rows)
{
colorIds.Add(new Color { Name = item["Name"].ToString(),
Code = item["ColorId"].ToString() });
}
getColorIdsRS.ColorIds = colorIds;
return getColorIdsRS;
}
Когда я вызываю GetColors из тестового клиента WCF, тело запроса:
<s:Body>
<GetColors xmlns="http://test.com/2011/05">
<req xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<UserCredentials>
<Username>test</Username>
<Password>test2</Password>
</UserCredentials>
</req>
</GetColors>
</s:Body>
Проблема с вышесказанным заключается в том, что я хочу использовать Username
и Password
узлы для CustomUserNameValidator
. Я не уверен, как заставить CustomUserNameValidator
распознать узлы GetColorIdsRQ
Имя пользователя и Пароль, чтобы он мог это проверить. Если вы заметили выше в методе GetColors
, я устанавливаю:
req.UserCredentials.UserName = "test";
req.UserCredentials.Password = "test";
но это не подтверждается, очевидно. Вот реализация моего CustomUserNamePasswordValidator
:
public class CustomUserNameValidator : UserNamePasswordValidator
{
public override void Validate(string userName, string password)
{
// check if the user is not test
if (userName != "test" || password != "test")
throw new FaultException("Username and Password Failed");
}
}
По сути, если я пройду:
req.UserCredentials.UserName = "test";
req.UserCredentials.Password = "test2";
CustomUserNameValidator должен выдавать исключение FaultException.
Обратите внимание, что в методе GetColors у меня есть комментарий "// Подтвердить имя пользователя и пароль", я знаю, что могу сделать:
CustomUserNameValidator val = new CustomUserNameValidator();
val.Validate(req.UserCredentials.UserName,req.UserCredentials.Password)
и выше будет вызывать метод Validate, но я знал, что он должен быть автоматическим, и тогда мне придется делать это в каждом отдельном методе.
Правда ли, что единственный способ вызова CustomUserNameValidator - это установить ClientCredentials в прокси-коде, например:
proxy.ClientCredentials.UserName.UserName = "test;
proxy.ClientCredentials.UserName.Password = "test;
Вышеуказанное вызовет вызов метода Validate, но если я не смогу выполнить вышеизложенное, и я установил имя пользователя и пароль в качестве свойств объекта Request, тогда Validate вызываться не будет, поэтому мой другой вариант просто иметь свой собственный метод Validate в каждой операции, которая требует его. Операция не будет вызываться в случае сбоя ClientCredentials, но в моем случае мне нужно вызвать операцию, а затем вернуть ответ SOAP с узлом ошибки с чем-то вроде «Неверное имя пользователя и / или пароль» вместо броска исключение FaultException.
Исходя из вышеизложенного, лучше ли избегать использования CustomUserNamePasswordValidator в моем случае?
В случае, если имя пользователя и пароль не могут быть установлены с помощью учетных данных клиента прокси, а скорее отправлены через тело запроса мыла, тогда кажется, что способ справиться с этим - обработать проверку в операционной и влияет ли это на параметры безопасности (например, есть ли точка для clientCredentialType = "Username")