Создание бизнес-приложений с помощью Silverlight - Безопасность приложений
ОГЛАВЛЕНИЕ
Безопасность приложений
Одним из важнейших требований приложения LOB является проверка подлинности; прежде чем агент центра обработки вызовов начнет смену, он проходит проверку подлинности, предоставляя идентификатор пользователя и пароль. В веб-приложениях ASP.NET это легко осуществить, воспользовавшись преимуществом поставщика членства и серверными элементами управления входом ASP.NET. В Silverlight имеются два способа обеспечить обязательность применения проверки подлинности: внешняя и внутренняя проверка подлинности.
Внешняя проверка подлинности реализуется очень просто и подобна реализации проверки подлинности приложений ASP.NET. При этом подходе проверка подлинности происходит на веб-странице, созданной на основе ASP.NET, до того, как отображается приложение Silverlight. Контекст проверки подлинности можно передать в приложение Silverlight через параметр InitParams до загрузки приложения Silverlight или посредством вызова веб-службы (для извлечения информации о состоянии проверки подлинности) после загрузки приложения.
Этот подход уместен, когда приложение Silverlight является частью большой системы на основе ASP.NET/HTML. Но в случаях, когда Silverlight является основной движущей силой приложения, естественно выполнять проверку подлинности в рамках Silverlight. С целью проверки учетных данных пользователя я буду использовать элемент управления PasswordBox из Silverlight 2 для перехвата пароля и проверки подлинности с помощью конечной точки ASP.NET AuthenticationService WCF. AuthenticationService, ProfileService и RoleService входят в новое пространство имен, System.Web.ApplicationServices, которое появилось в .NET Framework 3.5. На рис. 10 показан XAML для элемента управления Login, созданного для этой цели. Элемент управления Login вызывает ASP.NET AuthenticationService.LoginAsync(), передавая введенные пользователем идентификатор и пароль.
Рис. 11 Пользовательский элемент управления Login в Silverlight
Экран входа в систему центра обработки данных, показанный на рис. 11, выглядит просто, но вполне годится для целей демонстрационного примера. Я реализовал обработчик для работы с событием LoginCompleted внутри элемента управления таким образом, чтобы он был способен самостоятельно отображать диалоговые окна с сообщениями о неверном идентификаторе пользователя и сбросе пароля в случае более сложных реализаций. После успешной регистрации создается событие OnSuccessfulLogin для передачи родительскому элементу управления (в данном случае это Application.RootVisual) информации о необходимости отобразить первый экран приложения, заполненный сведениями о пользователе.
Обработчик LoginCompleted (ctrlLoginView_OnSuccessfulLogin), находящийся на главной странице Silverlight, вызовет службу профилей, размещенную на веб-сайте бизнес-служб, как показано на рис. 12. По умолчанию AuthenticationService не сопоставляется никакой конечной точке .svc; следовательно, я буду сопоставлять svc-файл физической реализации, как показано ниже:
<!-- AuthenticationService.svc -->
<%@ ServiceHost Language="C#" Service="System.Web.ApplicationServices.
AuthenticationService" %>
Рис. 12 Использование Login.xaml в рамках Page.xaml
<!-- Page.xaml of the main UserControl attached to RootVisual-->
<UserControl x:Class="AdvCallCenterClient.Page" ...>
<page:Login x:Name="ctrlLoginView" Visibility="Visible"
OnSuccessfulLogin="ctrlLoginView_OnSuccessfulLogin"/>
...
</UserControl>
<!-- Page.xaml.cs of the main UserControl attached to RootVisual-->
public partial class Page : UserControl
{
...
private void ctrlLoginView_OnSuccessfulLogin(object sender, EventArgs e)
{
Login login = sender as Login;
login.Visibility = Visibility.Collapsed;
CallBusinessProxy.UserProfileClient userProfile
= new CallBusinessProxy.UserProfileClient();
userProfile.GetUserCompleted += new
EventHandler<GetUserCompletedEventArgs>(userProfile_GetUserCompleted);
userProfile.GetUserAsync(login.txRepID.Text);
}
...
void userProfile_GetUserCompleted(object sender,
GetUserCompletedEventArgs e)
{
CallBusinessProxy.User user = e.Result;
UserToBindableUser utobu = new UserToBindableUser(user);
ClientGlobals.currentUser = utobu.Translate() as ClientEntities.User;
//all the time the service calls will be complete on a worker thread
//so the following check is redunant but done to be safe
if (!this.Dispatcher.CheckAccess())
{
this.Dispatcher.BeginInvoke(delegate()
{
this.registrationView.DataContext = ClientGlobals.currentUser;
this.ctrlLoginView.Visibility = Visibility.Collapsed;
this.registrationView.Visibility = Visibility.Visible;
});
}
}
}
Silverlight может вызывать только веб-службы, которые настроены для вызова средами сценариев, такими как AJAX. Подобно всем вызываемым службам AJAX, службе AuthenticationService необходим доступ к среде выполнения ASP.NET. Я обеспечиваю этот доступ настройкой <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/> непосредственно в узле <system.servicemodel>. Для того чтобы служба проверки подлинности могла быть вызвана процессом Silverlight, обеспечивающим вход в систему (или могла быть вызвана посредством AJAX), файл web.config должен быть настроен в соответствии с указаниями из статьи «Практическое руководство. Включение службы проверки подлинности WCF». Службы автоматически настроены для Silverlight, если они созданы с помощью расположенного в категории Silverlight шаблона служб WCF, поддерживающего Silverlight.
На рис. 13 показана измененная настройка с важными элементами, необходимыми для службы проверки подлинности. Кроме настройки службы я заменил в настройке SQL Server значение параметра aspnetdb, хранящего данные проверки подлинности. Machine.config определяет параметр LocalSqlServer, определяющий, что aspnetdb.mdf необходимо внедрить в каталог App_Data веб-узла. Данный параметр настройки отменяет значение по умолчанию и назначает aspnetdb, связанный с экземпляром SQL Server. Это легко изменить и назначить экземпляр базы данных, работающий на отдельной машине.
Рис. 13 Настройки для службы проверки подлинности ASP.NET
//web.config
<Configuration>
<connectionStrings>
<!-- removal and addition of LocalSqlServer setting will override the
default asp.net security database used by the ASP.NET Configuration tool
located in the Visul Studio Project menu-->
<remove name="LocalSqlServer"/>
<add name="LocalSqlServer" connectionString="Data
Source=localhost\SqlExpress;Initial Catalog=aspnetdb; ... />
</connectionStrings>
<system.web.extensions>
<scripting>
<webServices>
<authenticationService enabled="true" requireSSL="false"/>
</webServices>
</scripting>
</system.web.extensions>
...
<authentication mode="Forms"/>
...
<system.serviceModel>
<services>
<service name="System.Web.ApplicationServices.AuthenticationService"
behaviorConfiguration="CommonServiceBehavior">
<endpoint
contract="System.Web.ApplicationServices.AuthenticationService"
binding="basicHttpBinding" bindingConfiguration="useHttp"
bindingNamespace="http://asp.net/ApplicationServices/v200"/>
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="useHttp">
<!--for production use mode="Transport" -->
<security mode="None"/>
</binding>
</basicHttpBinding>
</bindings>
...
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
</system.serviceModel>
</configuration>
Чтобы сохранить инкапсуляцию элемента управления Login и поддерживать на этапе разработки ослабленную связь с родительским элементом управления, об успешном завершении процесса входа сообщается посредством создания события OnSuccessfulLogin. Application.RootVisual (являющийся классом Page) выполнит необходимый бизнес-процесс для отображения первого экрана после успешного входа в систему. Первый экран, отображенный после успешного входа, называется registrationView, как видно из метода userProfile_GetUserCompleted на рис. 12. Прежде чем будет отображено это представление, я получу информацию о пользователе, вызывая CallBusinessProxy.UserProfileClient.GetUserAsync(). Обратите внимание на асинхронный вызов службы, подобный вызову при интеграции бизнес-служб, которая будет обсуждаться далее.
Имейте в виду, что в предыдущей настройке не используется протокол защищенных сокетов (SSL); при создании производственных систем ее необходимо изменить так, чтобы использовался протокол SSL.
Рис. 14 Элемент управления OrderDetails.xaml с данными о заказе