Использование анонимной аутентификации в веб-сервисах
Использование анонимной аутентификации в веб-сервисах¶
Для интеграции с внешними системами, которые могут не являться частью инфраструктуры Windows и .NET, платформа “Тесса” поддерживает создание веб-сервисов SOAP, в которых выполняется анонимная аутентификация в платформе Tessa, т.е. пара логин/пароль передаётся через https в открытом виде, а именно в параметрах метода аутентификации Login.
Веб-сервис для интеграции создаётся и настраивается в сборках расширений платформы. Первым параметром методы веб-сервиса должны получить токен безопасности, сериализованный в виде строки, а прочие параметры определяются бизнес-логикой методов.
Интерфейс веб-сервиса располагается в сборке Tessa.Extensions.Shared:
[ServiceContract]
public interface IService
{
[OperationContract]
object GetData(string serializedToken, object parameter);
}
Класс веб-сервиса располагается в сборке Tessa.Extensions.Server.
[AspNetCompatibilityRequirements(
RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public sealed class Service : IService
{
[CheckToken(
TokenInFirstParameter = true,
UserAccessLevel = UserAccessLevel.User)]
public object GetData(string serializedToken, object parameter)
{
return parameter;
}
}
Атрибут CheckToken нужен для проверки того, что пользователь был авторизован в системе. Также при этом на сервер передаётся информация по локализации клиента и по его часовому поясу.
-
Если указать UserAccessLevel.Administrator, то метод сможет вызвать только администратор Tessa.
-
Если убрать атрибут, то любая внешняя система может вызвать метод от имени любого пользователя, а также не будет передана информация по локализации и часовому поясу клиента. При использовании анонимной аутентификации такая информация не передаётся в любом случае, но проверки выполняются.
-
“TokenInFirstParameter = true” определяет, что в первом параметре метода содержится строка с сериализованным токеном безопасности, который возвращается при аутентификации через Login или содержится в свойстве ApplicationStub.SerializedToken.
Регистрация выполняется на сервере в Tessa.Extensions.Server следующим образом:
unityContainer.RegisterType<IService, Service>(
new ContainerControlledLifetimeManager());
Регистрация при обращении со стороны клиента Tessa выполняется в Tessa.Extensions.Client:
using Tessa.Platform;
unityContainer.RegisterService<IService, ServiceClientGenerator>();
Класс ServiceClientGenerator также нужен для обращения со стороны клиента Tessa:
[ClientGenerator(typeof(IService))]
public sealed class ServiceClientGenerator : ICustomClientGenerator
{
public object CreateClient(string servicesAddress)
{
return ClientCreatorHelper.CreateClient<IService>(
servicesAddress,
"tessa/Service.svc/service");
}
}
В папке веб-приложения “tessa” необходимо разместить файл .svc с описанием веб-сервиса:
<% @ServiceHost Language="C#" Debug="true" Service="Tessa.Extensions.Server.Services.Service" Factory="Tessa.Service.WcfServiceFactory" %>
А в файле web.config веб-приложения “tessa” разместить конечную точку:
<service name="Tessa.Extensions.Server.Services.Service">
<endpoint address="service" binding="basicHttpBinding" bindingConfiguration="basicHttpBinding"
name="service" contract="Tessa.Extensions.Shared.Services.IService" />
<endpoint address="mex" binding="mexHttpsBinding" bindingConfiguration="mexHttpsBinding"
name="mex" contract="IMetadataExchange" />
</service>
Теперь со стороны внешней системы можно создать прокси для обращения к веб-сервису Service.svc для конечной точки service. Для доступа со стороны приложений Tessa достаточно получить интерфейс IService из контейнера Unity. А для обращения к веб-сервису из консольных утилит .NET или из юнит-тестов можно использовать код следующего вида:
using Microsoft.Practices.Unity;
using NUnit.Framework;
using Tessa.Platform.Runtime;
using Tessa.Extensions.Shared.Services;
...
var container = new UnityContainer()
.RegisterConnectionSettingsFromConfig()
.RegisterSessionsOnClient()
.RegisterService<IService>();
// получаем прокси к веб-сервису IService
var service = container.Resolve<IService>();
// тестируем метод веб-сервиса IService
object value = service.GetDataWithoutToken(serializedToken, 42);
Assert.That(value, Is.EqualTo(42));
// если нужно протестировать метод, требующий наличие сессии (и аутентификации)
var sessionClient = container.Resolve<ISessionClient>();
sessionClient.OpenSession("login", "password");
// и теперь вызываем метод веб-сервиса IService
object value2 = service.GetData(serializedToken, 42);
Assert.That(value, Is.EqualTo(42));