Главная страница статей --> Хитрости при программировании php, заметки по базам данных

Средства безопасности ASP.NET. Аутентификация

Источник: realcoding.net

[1 страница]
Давайте теперь перейдём к описанию процесса аутентификации непосредственно в рамках среды ASP.NET, где для вашего выбора предоставлены 3 вида аутентификации:

* Аутентификация Windows
* Формой
* Паспортом

Аутентификация Windows:


Как и следует из названия, этот метод основывается на использовании учётных записей Windows. Такой метод уместен, если вы создаёте приложение для локальной сети, и все действующие учётные записи и группы хранятся на заранее определённом домене. При этом нужно быть очень осторожными, назначая права доступа пользователям, поскольку вы одновременно задаёте и права для работы в Windows. Для того, чтобы настроить ASP.NET на работу в режиме Windows аутентификации необходимо изменить файл настройки Web-проекта Web.config или при необходимости конфигурационный файл всего сервера, расположенный по адресу WINDOWS_FOLDERMicrosoft.NET

Framework.NET versionCONFIGMachine.config. В нашем примере мы будем работать исключительно с файлом проекта – Web.config, в котором вам нужно найти раздел authentication и присвоить его атрибуту mode значение Windows:
<AUTHENTICATION mode="Windows"></AUTHENTICATION>

Теперь можно приступить непосредственно к программированию и реализации аутентификации на основе Windows. В помощь вам класс WindowsIdentity, который служит специально для работы с аутентификацией Windows. Вообще, для аутентификации, базирующейся на Windows, существуют два основных класса, предоставляемых .NET Framework:

* GenericIdentity – только реализует интерфейс IIdentity и не относится к какому-то определённому типу аутентификации
* WindowsIdentity – также является реализацией интерфейса IIdentity, но плюс ещё и включает методы, характерные только для аутентификации на основе Windows

Имя пользователя и группы хранятся в объекте WindowsIdentity в следующем формате: DOMAINUserName и DOMAINGroup соответственно. Исключение составляют лишь встроенные группы, например группа Administrators, для обращения к ней можно использовать строку подключения через WindowsIdentity: BUILTINAdministrators. Или же можно задать встроенную группу из перечисления System.Security.Principal.WindowsBuiltInRole.

Из рис. 1 видно, что объект WindowsIdentity позволяет получить имя пользователя; определить тип аутентификации; установить, была ли аутентификация проведена анонимно; также можно узнать, прошёл пользователь аутентификацию или нет, гость он или системный пользователь.


Рис. 1 – Объект WindowsIdentity

Поскольку в приложениях ASP.NET для обращения к объекту WindowsIdentity нужно будет выстроить следующую цепочку:

HttpContext.Current.User.Identity, то вы сможете также определить, к какой роли принадлежит текущий пользователь. Это можно достичь благодаря тому, что свойство User в этой цепочке реализует интерфейс Iprincipal, который позволяет определить принадлежность пользователя к определённой роли путём вызова функции IsInRole, имеющей следующий синтаксис:

Public Overridable Function IsInRole(ByVal role As String) As Boolean
    Member of
: System.Security.Principal.Iprincipal

Но давайте ненадолго отойдём от голой теории и попробуем реализовать практический пример. Для этого создайте новый проект ASP.NET Web Application и введите следующий код:
Default.aspx:

<%@ Page Language=vb AutoEventWireup=false Codebehind=default.aspx.vb Inherits=AuthSample.WebForm1%>
<!
DOCTYPE HTML PUBLIC -//W3C//DTD HTML 4.0 Transitional//EN>
<
html>
<
head>
<
title>Authentication Sample</title>
<
meta name=GENERATOR content=Microsoft Visual Studio .NET 7.1>
<
meta name=CODE_LANGUAGE content=Visual Basic .NET 7.1>
<
meta name=vs_defaultClientScript content=JavaScript>
<
meta name=vs_targetSchema content=http://schemas.microsoft.com/intellisense/ie5>
</
head>
<
body MS_POSITIONING=GridLayout>
<
form id=Form1 method=post runat=server>

</
form>
</
body>
</
html>

Default.aspx.vb:

Public Class WebForm1
Inherits System
.Web.UI.Page

#Region “ Web Form Designer Generated Code “

‘This call is required by the Web Form Designer.
<
System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()

End Sub

‘NOTE
: The following placeholder declaration is required by the Web Form Designer.
‘Do not delete or move it.
Private designerPlaceholderDeclaration As System.Object

Private Sub Page_Init
(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
‘CODEGEN
: This method call is required by the Web Form Designer
‘Do not modify it using the code editor
.
InitializeComponent()
End Sub

#End Region

Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim s
As String

s
= <p><b>Name:</b> & HttpContext.Current.User.Identity.Name & </p>& _
<p><b>Authentication type:</b> & HttpContext.Current.User.Identity.AuthenticationType.ToString & </p>& _
<p><b>Is authenticated:</b> & HttpContext.Current.User.Identity.IsAuthenticated.ToString & </p>& _
<p><b>Is admin:</b> & HttpContext.Current.User.IsInRole(“Administrator”).ToString & </p>
Response
.Write(s)
End Sub

End
Class

Если был выбран режим аутентификации Windows и настройки IIS не вызвали никаких конфликтных ситуаций, то вы получите соответствующую информацию о своём текущем пользователе. Если же поле имени пользователя и типа аутентификации оказались пустыми, то вам нужно просто настроить IIS, для этого выполните следующие действия:

1. Откройте IIS и найдите виртуальный каталог с этим приложением
2. Откройте окно свойств для этого каталога и перейдите во вкладку Безопасность каталога. В рамке Анонимный доступ и проверка подлинности нажмите кнопку Изменить…
3. В появившемся окне (рис. 2) снимите флажок Анонимный доступ


Рис. 2 – Настройка IIS

На этом мы закончим рассмотрение аутентификации на основе Windows и перейдём к аутентификации формой.

Аутентификация формой:


Аутентификация формой или, как её ещё называют аутентификация на основе Cookie-файлов, имеет ряд преимуществ над аутентификацией Windows.

* Во-первых, вы имеете возможность самому определить на свой вкус и цвет или на вкус и цвет пользователя внешний вид формы регистрации вместо однотипного окна регистрации Windows.
* Во-вторых, вы полностью контролируете вводимую информацию
* Сведения о пользователях теперь может храниться не только в SAM или Active Directory, но и в любом другом хранилище, в частности: база данных, каталог LDAP, XML-файлы или же обычный текстовый файл.
* Отпадает необходимость связывать политику безопасности сервера с политикой Web-приложения, поскольку, как уже было ранее сказано, все сведения о пользователях можно вынести в отдельное хранилище данных без каких-либо пересечений с учётными записями ОС.

Но, не смотря на такое изобилие возможностей аутентификации на основе формы, существует и одно весомое ограничение – пользователь должен разрешить применение cookie-файлов. Если его не будет, то аутентификация формой с применением средств ASP.NET работать не будет. Обратите внимание на слова “…с применением средств ASP.NET…”. Это означает, что не будет работать механизм, освобождающий разработчика от рутинных операций бесконечных проверок, иными словами, все запросы, поступившие от пользователя, ещё не прошедшего аутентификацию, переадресовываются на страницу регистрации, где он вводит необходимую информацию (чаще всего имя пользователя и пароль). Полученные сведения передаются среде ASP.NET, где происходит их верификация. В случае успеха пользователю передаётся cookie-файл, в котором содержится удостоверение об авторизации (Authorization ticket), имя пользователя и ключ для последующего получения идентификатора. В результате все последующие обращения броузера будут содержать в заголовках сведения об авторизации, направляемые на проверку в среду ASP.NET. Поэтому, если пользователь не поддерживает cookie, то все проверки о том, прошёл ли он аутентификацию, нужно будет осуществлять вручную, например, в предыдущих версиях ASP для этого применяли объект Session, примерно, в следующей форме:

If Not Session(“Registered”) = “1” Then
Response
.Redirect(“login.asp”)
End If

Для использования аутентификации формой сперва нужно настроить конфигурацию Web-проекта. Для этого измените содержимое тэга <authentication> файла Web.config следующим образом:

<authentication mode=”Forms”>
<
forms name=”ASP_XML_Form” loginUrl=”login.aspx” protection=”All”
     timeout
=”30” path=/” requireSSL=”false” slidingExpiration=”true” />
</
authentication>

Давайте подробнее рассмотрим вышеприведённый код. Атрибут mode тэга <authentication> определяет способ аутентификации. В предыдущих примерах мы использовали значение Windows, которое настраивало аутентификацию в режим аутентификации средствами Windows, теперь для работы на основе форм мы применяем режим Forms. Кроме этих двух констант существуют ещё 2: Passport и None – первая из них определяет аутентификацию на основе паспорта, о которой речь пойдёт позже, вторая отключает её вообще. Следующий тэг (<forms>) присущ только аутентификации на основе формы и включает в себя следующие сведения:

* name – имя cookie-файла, в который будут внесены данные об успешном прохождении аутентификации
* loginUrl – определяет адрес страницы, на которую будет переадресован пользователь для прохождения регистрации
* protection – принимает значения AllNoneEncryptionValidation и определяет способ защиты данных в cookie-файлах. Из допустимых значений видно, что можно ничего не делать с полученными данными и принимать их такими, какие они есть; можно сверять их; можно шифровать; а также есть возможность объединить верификацию с криптографией – такое значение используется по умолчанию.
* timeout – определяет промежуток времени в секундах, в течение которого cookie будет доступен
* path – этот атрибут задаёт полный путь к cookie-файлу. По умолчанию он содержит косую черту (/), которая раскрывает все пути. Менять этот параметр не рекомендуется, потому что некоторые броузеры чувствительны к регистру в пути, потому в результате изменений этого параметра вы можете отрезать некоторых пользователей от возможности проходить аутентификацию.
* requireSSL – этот атрибут принимает значения True или False (по умолчанию) и устанавливает необходимость применения протокола защищённых сокетов (SSL – Secured Sockets Layer)
* slidingExpiration – указывает, нужно ли пересоздавать cookie и удостоверение об авторизации, если истекает таймаут. Принимает значения true (по умолчанию) или false.

Выше были описаны все возможные атрибуты раздела forms,но для корректной работы приложения достаточно использовать лишь 3 из них, как это показано в следующем листинге:

<forms name=”ASP_XML_Form” loginUrl=”login.aspx” protection=”All” />

Аутентификация формой с использованием отдельных XML-файлов:


Давайте теперь создадим простую страницу регистрации пользователей, которая сверяет введённые имя и пароль с данными из XML-файла. Для этого сперва создайте XML-файл с именем users.xml следующего образца:
users.xml:

<?xml version=”1.0” encoding=”utf-8” ?>

<users>
    <user>
        <name>John</name>
        <password>one</password>
    </user>
    <user>
        <name>Mike</name>
        <password>two</password>
    </user>
    <user>
        <name>Bill</name>
        <password>three</password>
    </user>
</users>

База пользователей готова – теперь можно приступить к созданию пробного проекта регистрации пользователей. Весь необходимый код приведён ниже:
Default.aspx:

<%@ Page Language=”vb” AutoEventWireup=”false” Codebehind=”default.aspx.vb” Inherits=”FormAuth._default”%>
<!
DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.0 Transitional//EN”>
<html>
<
head>
<
title>default</title>
<
meta name=”GENERATOR” content=”Microsoft Visual Studio .NET 7.1”>
<
meta name=”CODE_LANGUAGE” content=”Visual Basic .NET 7.1”>
<
meta name=vs_defaultClientScript content=”JavaScript”>
<
meta name=vs_targetSchema content=”http://schemas.microsoft.com/intellisense/ie5”>
</head>
<
body MS_POSITIONING=”GridLayout”>

<
form id=”Form1” method=”post” runat=”server”>

</
form>

</
body>
</
html>

Default.aspx.vb:

Imports System.Web.Security

Public
Class _default
Inherits System
.Web.UI.Page

#Region “ Web Form Designer Generated Code “

‘This call is required by the Web Form Designer.
<
System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()

End Sub

‘NOTE
: The following placeholder declaration is required by the Web Form Designer.
‘Do not delete or move it.
Private designerPlaceholderDeclaration As System.Object

Private Sub Page_Init
(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
‘CODEGEN
: This method call is required by the Web Form Designer
‘Do not modify it using the code editor
.
InitializeComponent()
End Sub

#End Region

Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
‘Put user code to initialize the page here
If context.Current.User.Identity.Name = “” Then
Response
.Redirect(“login.aspx”)
Else
Response.Write(<h2><I>Hello “ & context.Current.User.Identity.Name & </I></h2>)
End If
End Sub
End
Class

login.aspx:

<%@ Page Language=”vb” AutoEventWireup=”false” Codebehind=”login.aspx.vb” Inherits=”FormAuth.WebForm1”%>
<!
DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.0 Transitional//EN”>
<HTML>
    <
HEAD>
        <
title>Registration</title>
        <
meta name=”GENERATOR” content=”Microsoft Visual Studio .NET 7.1”>
        <
meta name=”CODE_LANGUAGE” content=”Visual Basic .NET 7.1”>
        <
meta name=”vs_defaultClientScript” content=”JavaScript”>
        <
meta name=”vs_targetSchema” content=”http://schemas.microsoft.com/intellisense/ie5”>
   
</HEAD>
    <
body MS_POSITIONING=”GridLayout”>
        <
form id=”Form1” method=”post” runat=”server”>
            <
table border>
                <
tr>
                    <
td>Name</td>
                    <
td><asp:TextBox ID=”txtName” Runat=server></asp:TextBox></td>
                </
tr>
                <
tr>
                    <
td>Password</td>
                    <
td><asp:TextBox ID=”txtPassword” Runat=server TextMode=Password>
                        </
asp:TextBox></td>
                </
tr>
                <
tr>
                    <
td colspan=2 align=right><asp:Button ID=”btnLogin” Text=”Login”
                        Runat
=server></asp:Button></td>
                </
tr>
            </
table>
            
            <
p><asp:Label ID=”lbl” Runat=server Visible=False ForeColor=Maroon Font-Bold=True>
               
Authentication failed</asp:Label></p>
        </
form>
    </
body>
</
HTML>

login.aspx.vb:

Imports System.Xml
Imports System
.Web.Security

Public
Class WebForm1
Inherits System
.Web.UI.Page

Protected WithEvents txtName
As System.Web.UI.WebControls.TextBox
Protected WithEvents txtPassword
As System.Web.UI.WebControls.TextBox
Protected WithEvents lbl
As System.Web.UI.WebControls.Label
Protected WithEvents btnLogin
As System.Web.UI.WebControls.Button

#Region “ Web Form Designer Generated Code “

‘This call is required by the Web Form Designer.
<
System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()

End Sub

‘NOTE
: The following placeholder declaration is required by the Web Form Designer.
‘Do not delete or move it.
Private designerPlaceholderDeclaration As System.Object

Private Sub Page_Init
(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
‘CODEGEN
: This method call is required by the Web Form Designer
‘Do not modify it using the code editor
.
InitializeComponent()
End Sub

#End Region

Private Sub btnLogin_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnLogin.Click
Dim xd
As New XmlDocument, xr As XmlNodeReader
Dim sName
As String, sPass As String

Открываем XML-файл
xd.Load(Server.MapPath(“users.xml”))
‘ Активируем XmlNodeReader
xr = New XmlNodeReader(xd.Item(“users”))

Ищем нужного пользователя
While xr.Read
If xr.Name = “name” And xr.NodeType = XmlNodeType.Element Then
sName
= xr.ReadString
Если не то имя пользователя, то переходим к другому
If sName <> txtName.Text Then xr.Skip()
ElseIf xr.Name = “password” And xr.NodeType = XmlNodeType.Element Then
If xr.ReadString() = txtPassword.Text Then
Если пароли совпали, значит аутентификация проведена успешно
FormsAuthentication
.RedirectFromLoginPage(txtName.Text, True)
Else
Если нет, то переходим к другому пользователю
xr.Skip()
End If
End If
End While

Если эта строка выполняется, значит данные о пользователе были введены неверно
lbl
.Visible = True
End Sub
End
Class

Давайте теперь проведём “разбор полётов”: вышеприведённый код содержит в себе 2 страницы. Все действия начинаются на странице default.aspx, в которой происходит проверка, есть ли у текущего пользователя имя:

If context.Current.User.Identity.Name = “” Then
Response
.Redirect(“login.aspx”)
Else
Response.Write(<h2><I>Hello “ & context.Current.User.Identity.Name & </I></h2>)
End If

Если оно есть, то на экран будет выведено приветствие, в противном случае – пользователь будет переадресован на страницу регистрации login.aspx, где ему будет предложено ввести своё имя и пароль. Введённые сведения сверяются с данными из XML файла. Если пользователь не будет найден, появится сообщение об ошибке (рис. 3), в ином случае он будет благополучно переадресован на исходную страницу default.aspx, которая, обнаружив, что у текущего пользователя имя определено, поприветствует его.


Рис. 3 – Неверные данные при регистрации

Если вы успешно прошли аутентификацию и увидели приветствие, то закройте окно броузера и попробуйте заново запустить страницу default.aspx. Вы сразу увидите перед собой приветствие для того пользователя, чьё имя вы вводили в последний раз. Дело в том, что при регистрации мы сохранили на машине клиента cookie-файл. Это произошло в тот момент, когда мы в коде вызывали функцию RedirectFromLoginPage, передав её параметру CreatePersistentCookie значение True:

FormsAuthentication.RedirectFromLoginPage(txtName.Text, True)

Для того чтобы исключить передачу cookie файла достаточно вызвать эту функцию со значением False параметра CreatePersistentCookie. Или есть другой способ – в странице default.aspx добавьте обработчик события выгрузки страницы со следующим кодом:

Private Sub Page_Unload(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Unload
FormsAuthentication
.SignOut()
End Sub

В результате, после выгрузки главной страницы пользователь будет регистрироваться о выходе.

Аутентификация формой с использованием файла конфигурации:


В предыдущем примере мы хранили все данные о пользователях в отдельном XML-файле, но оказывается ASP.NET предоставляет возможность хранить сведения об аккаунтах прямо в файле конфигурации Web-проекта. Преимуществом этого метода является то, что для его реализации требуется значительно меньше программного кода, поскольку в данном случае программисту не нужно вручную просматривать XML-файл в поисках соответствующих совпадений – он лишь вызывает одну единственную функцию, которая и решает всё дело. Для того чтобы понять принцип работы этого механизма, давайте ещё раз обратимся к файлу конфигурации, а точнее к тэгу forms. Этот тэг помимо уже описанных ранее атрибутов может также включать раздел <credentials> - сертификаты:
Web.config:

<authentication mode=”Forms”>
    <
forms name=”ASP_XML_Form” loginUrl=”login.aspx” protection=”All” timeout=”30” path=/
        requireSSL
=”false” slidingExpiration=”true”>
        <
credentials passwordFormat=”Clear”>
            <
user name=”John” password=”one”/>
            <
user name=”Mike” password=”two”/>
            <
user name=”Bill” password=”three”/>
        </
credentials>
    </
forms>
</
authentication>

Как видно из вышеприведённого листинга, тэг credentials содержит один единственный атрибут – passwordFormat. Этот параметр определяет способ хранения пароля и принимает следующие значения:

* Clear – пароль сохраняется без каких-либо изменений
* SHA1 – пароль хэшируется методом SHA1 (Secure Hash Algorithm версии 1)
* MD5 – пароль хэшируется методом MD5 (Message Digest версии 5)

Если вы выберите какой-нибудь из алгоритмов хэширования, то пароль уже нельзя будет хранить в исходной форме в файле конфигурации – его нужно будет сперва хэшировать и лишь потом присвоить полученный результат атрибуту password. В противном случае, когда ASP.NET будет проводить аутентификацию, пароли просто не совпадут.

Теперь, когда мы имеем свежеиспечённую базу учётных записей, давайте вернёмся к предыдущему приложению и изменим код обработчика события нажатия кнопки регистрации в странице login.aspx:
login.aspx.vb:

Private Sub btnLogin_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnLogin.Click
If FormsAuthentication.Authenticate(txtName.Text, txtPassword.Text) Then
Если пользователь найден в разделе сертификатов, значит, регистрация проведена
‘ успешно
FormsAuthentication.RedirectFromLoginPage(txtName.Text, False)
Else
Иначе – выводим сообщение об ошибке
lbl
.Visible = True
End
If
End Sub

Теперь сравните этот код с тем, который использовался в предыдущем примере. Как видите, он сократился от множества условий и переборов до всего одного запроса, возвращающего True или False.

Мы специально сейчас не станем рассматривать пример кода, работающего с хэшированными паролями, чтобы не торопить события. Дело в том, что в 3-й части этой статьи, которая будет посвящена криптографии, вы узнаете обо всех тонкостях хэширования и шифрования данных и сможете сами применить эти методы на практике.

Аутентификация формой с использованием базы данных:


Давайте теперь рассмотрим пример работы с ещё одним хранилищем данных о пользователях – с базой данных MS SQL Server. Большинство динамических сайтов используют базы данных для хранения содержимого сайта. Сведения о пользователях также не являются исключением и вполне могут занять своё место в общем пуле данных. Для того, чтобы своими глазами увидеть, как всё это происходит, давайте создадим тестовое приложение, которое вновь будет основано на уже известной нам странице регистрации, применяемой в предыдущих примерах. Прежде всего, необходимо приготовить базу данных, для этого откройте утилиту SQL Query Analyzer и выполните в ней следующий код, написанный на языке tSQL:
FormAuthUsers.sql:

--Create database ‘FormAuthUsers’ and add table ‘Users’
CREATE DATABASE FormAuthUsers
GO
USE FormAuthUsers
GO
CREATE TABLE
[Users] (
    [
ID] [int] IDENTITY (1, 1) NOT NULL,
    [
UserName] [nvarchar] (50),
    [
Password] [nvarchar] (50),
   
CONSTRAINT [PK_Users] PRIMARY KEY CLUSTERED
   
([ID]) ON [PRIMARY]
)
ON [PRIMARY]

GO

--Fill table ‘Users’
INSERT INTO Users
(UserName, Password)
VALUES(‘John’, ‘one’)
GO
INSERT INTO Users
(UserName, Password)
VALUES(‘Mike’, ‘two’)
GO
INSERT INTO Users
(UserName, Password)
VALUES(‘Bill’, ‘three’)

GO

--Create procedure ‘FindUser’
CREATE PROCEDURE FindUser
   
@Name nvarchar(50),
    @
Password nvarchar(50)
AS
   
SELECT COUNT(ID) FROM Users
    WHERE UserName
= @Name AND Password = @Password

GO



Похожие статьи:
- Сложные графики и диаграммы в ASP.NET. Часть пятая – интерактивность.
- Сила параметров XmlElement в Web-методах ASP.NET
- Путеводитель по обмену ссылками
- Частичная проверка правильности ввода данных.
- Postback и Query String - совместить несовместимое
- Секреты правильной раскрутки сайтов
- Средства безопасности ASP.NET. Аутентификация
- Новое в ASP.NET 2. Профили пользователей
- Ожидание выполнения длительного процесса в ASP.NET
- Сайты доноры - источники траффика
- Роль контента в раскрутке сайта
- Лекция 6. Работа с базами данных.
- Лекция 4. Серверные элементы управления Продолжение.


Оглавление | Обсудить на форуме | Главная страница сайта | Карта сайта |

Контакты
Редакция:
[0.002]