Добавлен: 26.05.2023
Просмотров: 83
Скачиваний: 3
СОДЕРЖАНИЕ
1. Теоретические аспекты изучения клиентских программ
1.1. Обзор программных средств для создания баз данных
1.2. Использование служб клиентских приложений
2.Создание клиентского приложения
2.1.Создание узла служб приложений
2.2.Настройка членства и ролей
2.3. Добавление проверки подлинности с помощью форм
VB
Public Function GetCredentials() As _
ClientFormsAuthenticationCredentials Implements _
IClientFormsAuthenticationCredentialsProvider.GetCredentials
If Me.ShowDialog() = DialogResult.OK Then
Return New ClientFormsAuthenticationCredentials( _
UsernameTextBox.Text, PasswordTextBox.Text, _
rememberMeCheckBox.Checked)
Else
Return Nothing
End If
End Function
В следующей процедуре для C# приводится полный код создания простого диалогового окна входа. Макет этого диалогового окна достаточно приблизителен, однако главный интерес здесь представляет реализация метода GetCredentials.
Создание диалогового окна входа как поставщика учетных данных в C#
- В окне Обозреватель решений щелкните проект ClientAppServicesDemo, а затем в меню Проект выберите пункт Добавить класс.
- В диалоговом окне Добавление нового элемента измените Имя на Login.cs и нажмите кнопку Добавить.
В редакторе кода откроется файл Login.cs.
- Замените код по умолчанию представленным ниже.
C#
using System.Windows.Forms;
using System.Web.ClientServices.Providers;
namespace ClientAppServicesDemo
{
class Login : Form,
IClientFormsAuthenticationCredentialsProvider
{
private TextBox usernameTextBox;
private TextBox passwordTextBox;
private CheckBox rememberMeCheckBox;
private Button OK;
private Button cancel;
private Label label1;
private Label label2;
public ClientFormsAuthenticationCredentials GetCredentials()
{
if (this.ShowDialog() == DialogResult.OK)
{
return new ClientFormsAuthenticationCredentials(
usernameTextBox.Text, passwordTextBox.Text,
rememberMeCheckBox.Checked);
}
else
{
return null;
}
}
public Login()
{
InitializeComponent();
}
private void CloseForm(object sender, System.EventArgs e)
{
this.Close();
}
private void InitializeComponent()
{
this.label1 = new System.Windows.Forms.Label();
this.usernameTextBox = new System.Windows.Forms.TextBox();
this.label2 = new System.Windows.Forms.Label();
this.passwordTextBox = new System.Windows.Forms.TextBox();
this.rememberMeCheckBox = new System.Windows.Forms.CheckBox();
this.OK = new System.Windows.Forms.Button();
this.cancel = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(13, 13);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(58, 13);
this.label1.TabIndex = 0;
this.label1.Text = "&User name";
//
// usernameTextBox
//
this.usernameTextBox.Location = new System.Drawing.Point(13, 30);
this.usernameTextBox.Name = "usernameTextBox";
this.usernameTextBox.Size = new System.Drawing.Size(157, 20);
this.usernameTextBox.TabIndex = 1;
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(13, 57);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(53, 13);
this.label2.TabIndex = 2;
this.label2.Text = "&Password";
//
// passwordTextBox
//
this.passwordTextBox.Location = new System.Drawing.Point(13, 74);
this.passwordTextBox.Name = "passwordTextBox";
this.passwordTextBox.PasswordChar = '*';
this.passwordTextBox.Size = new System.Drawing.Size(157, 20);
this.passwordTextBox.TabIndex = 3;
//
// rememberMeCheckBox
//
this.rememberMeCheckBox.AutoSize = true;
this.rememberMeCheckBox.Location = new System.Drawing.Point(13, 101);
this.rememberMeCheckBox.Name = "rememberMeCheckBox";
this.rememberMeCheckBox.Size = new System.Drawing.Size(94, 17);
this.rememberMeCheckBox.TabIndex = 4;
this.rememberMeCheckBox.Text = "&Remember me";
this.rememberMeCheckBox.UseVisualStyleBackColor = true;
//
// OK
//
this.OK.DialogResult = System.Windows.Forms.DialogResult.OK;
this.OK.Location = new System.Drawing.Point(13, 125);
this.OK.Name = "OK";
this.OK.Size = new System.Drawing.Size(75, 23);
this.OK.TabIndex = 5;
this.OK.Text = "&OK";
this.OK.UseVisualStyleBackColor = true;
//
// cancel
//
this.cancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.cancel.Location = new System.Drawing.Point(95, 125);
this.cancel.Name = "cancel";
this.cancel.Size = new System.Drawing.Size(75, 23);
this.cancel.TabIndex = 6;
this.cancel.Text = "&Cancel";
this.cancel.UseVisualStyleBackColor = true;
//
// Login
//
this.AcceptButton = this.OK;
this.CancelButton = this.cancel;
this.ClientSize = new System.Drawing.Size(187, 168);
this.Controls.Add(this.cancel);
this.Controls.Add(this.OK);
this.Controls.Add(this.rememberMeCheckBox);
this.Controls.Add(this.passwordTextBox);
this.Controls.Add(this.label2);
this.Controls.Add(this.usernameTextBox);
this.Controls.Add(this.label1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "Login";
this.Text = "Login";
this.ResumeLayout(false);
this.PerformLayout();
}
}
}
Теперь можно запустить приложение. Отобразится диалоговое окно входа. Чтобы проверить код, попробуйте вводить разные учетные данные, как действительные, так и недействительные. Доступ к форме должен открываться только при вводе действительных учетных данных. Допустимые имена пользователей — employee и manager с паролями employee! и manager! соответственно.
Добавление функций на основе ролей
В следующей процедуре вы добавите в форму кнопку, которая будет отображаться только для пользователей с ролью "manager".
Изменение пользовательского интерфейса в зависимости от роли пользователя
- В Обозревателе решений найдите проект ClientAppServicesDemo, щелкните форму Form1 и выберите в главном меню Visual Studio пункты Вид | Конструктор.
- В конструкторе откройте меню Панель элементов и добавьте в форму элемент управления Button.
- В окне Свойства задайте следующие свойства кнопки.
Свойство |
Значение |
(Имя) |
managerOnlyButton |
Text |
&Manager task |
Показывается |
False |
- В редакторе кода формы Form1 добавьте в конце метода Form1_Load приведенный ниже код.
Этот код вызывает метод DisplayButtonForManagerRole, который будет добавлен в следующем шаге.
C#
VB
DisplayButtonForManagerRole();
- В конце класса Form1 добавьте приведенный ниже метод.
Этот метод вызывает метод IsInRole интерфейса IPrincipal, возвращенного свойством Thread.CurrentPrincipal (static). Для приложений, настроенных на использование служб клиентских приложений, это свойство возвращает класс ClientRolePrincipal. Поскольку этот класс реализует интерфейс IPrincipal, необязательно явно ссылаться на него.
Если пользователю назначена роль "manager", метод DisplayButtonForManagerRole присваивает свойству Visible кнопки managerOnlyButton значение true. При вызове исключения WebException этот метод также отображает сообщение об ошибке, означающее, что служба ролей недоступна.
При истечении допустимого времени в системе метод IsInRole всегда возвращает значение false. Этого не происходит, если приложение вызывает метод IsInRole один раз вскоре после проверки подлинности, как показано в примере кода, который используется в этом руководстве. Если необходимо, чтобы приложение извлекало роли пользователей в другое время, вы можете добавить код для повторной проверки пользователей, чье допустимое время в системе истекло. Если всем допустимым пользователям назначены роли, вы можете выявлять истечение допустимого времени, вызывая метод ClientRoleProvider.GetRolesForUser. Если роли не возвращаются, значит время истекло. Пример реализации этой возможности — метод GetRolesForUser. Данная функция необходима лишь в случае, если в параметрах приложения вы выбрали пункт Требовать, чтобы пользователи повторяли вход, если у файла cookie сервера истек срок действия.
C#
VB
private void DisplayButtonForManagerRole()
{
try
{
if (Thread.CurrentPrincipal.IsInRole("manager"))
{
managerOnlyButton.Visible = true;
}
}
catch (System.Net.WebException)
{
MessageBox.Show("Unable to access the role service.",
"Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
В случае успешной проверки подлинности поставщик проверки подлинности клиента назначает свойство Thread.CurrentPrincipal экземпляру класса ClientRolePrincipal. Этот класс реализует метод IsInRole — функции делегируются заданному поставщику ролей. Как и ранее, в коде приложения не требуются прямые ссылки на поставщика услуг.
Теперь можно запустить приложение и войти в систему с именем пользователя "employee", чтобы убедиться, что кнопка не отображается. После этого попробуйте войти с именем "manager" — кнопка должна отображаться.
3. Доступ к веб-параметрам
В следующей процедуре вы добавите на форму текстовое поле и привяжете его к веб-параметрам. Как и в ранее описанном коде, с помощью которого были реализованы проверка подлинности и доступ к функциям в зависимости от ролей, в коде ваших параметров не требуется прямых ссылок на поставщика параметров. Вместо этого используется строго типизированный класс Settings(Properties.Settings.Default в C# и My.Settings в Visual Basic), созданный в вашем проекте с помощью Visual Studio.
Использование веб-параметров в пользовательском интерфейсе
- Проверьте область уведомлений на панели задач и убедитесь, что Сервер веб-разработки ASP.NET запущен. Если вы останавливали сервер, перезапустите приложение и закройте диалоговое окно входа. Сервер будет запущен автоматически.
- В окне Обозреватель решений щелкните проект ClientAppServicesDemo, а затем в меню Проект выберите пункт Свойства ClientAppServicesDemo.
Откроется конструктор проектов.
- На вкладке Параметры выберите команду Загрузить веб-параметры.
Появится диалоговое окно Имя для входа.
- Введите учетные данные для пользователя "employee" или "manager" и нажмите кнопку Войти. Получить доступ веб-параметрам, которые будут использоваться в дальнейшем, могут только пользователи, прошедшие проверку подлинности. Если нажать кнопку Пропустить вход, параметры не будут загружены.
В конструкторе появится параметр WebSettingsTestText со значением по умолчанию DefaultText. В вашем проекте также будет создан класс Settings, содержащий свойство WebSettingsTestText.
- В Обозревателе решений найдите проект ClientAppServicesDemo, щелкните форму Form1 и выберите в главном меню Visual Studio пункты Вид | Конструктор.
- В конструкторе добавьте на форму элемент управления TextBox.
- В окне Свойства укажите для параметра (Name) значение webSettingsTestTextBox.
- В редакторе кода добавьте в конце метода Form1_Load приведенный ниже код.
Этот код вызывает метод BindWebSettingsTestTextBox, который будет добавлен в следующем шаге.
C#
VB
BindWebSettingsTestTextBox();
- В конце класса Form1 добавьте приведенный ниже метод.
Этот метод привязывает свойство Text метода webSettingsTestTextBox к свойству WebSettingsTestText класса Settings, создание которого описывалось ранее в этой процедуре. При вызове исключения WebException этот метод также отображает сообщение об ошибке, означающее, что служба веб-параметров недоступна.
C#
VB
private void BindWebSettingsTestTextBox()
{
try
{
this.webSettingsTestTextBox.DataBindings.Add("Text",
Properties.Settings.Default, "WebSettingsTestText");
}
catch (WebException)
{
MessageBox.Show("Unable to access the Web settings service.",
"Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
C#
VB
webSettingsTestTextBox.Text =
Properties.Settings.Default.WebSettingsTestText;
- В конструкторе выберите форму, а затем в окне Свойства нажмите кнопку События.
- Выберите событие FormClosing и нажмите клавишу ВВОД, чтобы создать обработчик события.
- Замените созданный метод приведенным ниже кодом.
Обработчик события FormClosing вызывает метод SaveSettings, также используемый функцией выхода, которая будет добавлена в следующем разделе. Метод SaveSettings сначала проверяет, не вышел ли пользователь из системы. Это достигается путем проверки свойства AuthenticationTypeIIdentity, возвращенного текущим субъектом. Текущий субъект устанавливается с помощью свойства CurrentPrincipal (static). Если пользователь прошел проверку подлинности служб клиентских приложений, используется проверка подлинности типа "ClientForms". Метод SaveSettings не может просто проверить свойство IIdentity.IsAuthenticated, поскольку после выхода у пользователя может иметься допустимое удостоверение Windows.
Если пользователь не выходил из системы, метод SaveSettings вызывает метод Save, принадлежащий классу Settings. Создание этого класса описывалось выше. При истечении срока действия файла cookie проверки подлинности этот метод может вызвать исключение WebException. Это возможно лишь в случае, если в параметрах приложения вы выбрали пункт Требовать, чтобы пользователи повторяли вход, если у файла cookie сервера истек срок действия. Дополнительные сведения см. в разделе Практическое руководство. Настройка служб клиентских приложений. При истечении срока действия файлов cookie метод SaveSettings вызывает метод ValidateUser для отображения диалогового окна входа в систему. В случае успешного входа пользователя метод SaveSettings вызывает сам себя, предпринимая попытку повторного сохранения параметров.
Как и в предшествующем коде, если удаленная служба недоступна, метод SaveSettings отображает сообщение об ошибке. Если поставщик параметров не может получить доступ к удаленной службе, параметры сохраняются в локальном кэше и перезагружаются при повторном запуске приложения.
C#
VB
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
SaveSettings();
}
private void SaveSettings()
{
// Return without saving if the authentication type is not
// "ClientForms". This indicates that the user is logged out.
if (!Thread.CurrentPrincipal.Identity.AuthenticationType
.Equals("ClientForms")) return;
try
{
Properties.Settings.Default.Save();
}
catch (WebException ex)
{
if (ex.Message.Contains("You must log on to call this method."))
{
MessageBox.Show(
"Your login has expired. Please log in again to save " +
"your settings.", "Attempting to save settings...");
try
{
// Call ValidateUser with empty strings in order to
// display the login dialog box configured as a
// credentials provider.
if (!Membership.ValidateUser(String.Empty, String.Empty))
{
MessageBox.Show("Unable to authenticate. " +
"Settings were not saved on the remote service.",
"Not logged in", MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
else
{
// Try again.
SaveSettings();
}
}
catch (System.Net.WebException)
{
MessageBox.Show(
"Unable to access the authentication service. " +
"Settings were not saved on the remote service.",
"Not logged in", MessageBoxButtons.OK,
MessageBoxIcon.Warning);
}
}
else
{
MessageBox.Show("Unable to access the Web settings service. " +
"Settings were not saved on the remote service.",
"Not logged in", MessageBoxButtons.OK,
MessageBoxIcon.Warning);
}
}
}
- В конце класса Form1 добавьте приведенный ниже метод.
Этот код обрабатывает событие ClientSettingsProvider.SettingsSaved и отображает предупреждение, если какие-либо параметры не удалось сохранить. Если служба параметров недоступна или истек срок действия файла cookie проверки подлинности, событие SettingsSaved не происходит. Событие SettingsSaved происходит, например, если пользователь уже вышел из системы. Вы можете проверить этот обработчик событий, непосредственно перед вызовом метода Save добавив в метод SaveSettings код выхода. Код выхода, который можно при этом использовать, описывается в следующем разделе.