Создание бизнес-приложений с помощью 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 с данными о заказе