Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

ASP.NET MVC Урок 1-F / ASP.NET MVC Урок 6

.pdf
Скачиваний:
45
Добавлен:
09.03.2016
Размер:
456.99 Кб
Скачать

$63 1(7 09& ǻȘȖȒ ǨȊȚȖȘȐȏȈȞȐȧ tutorial

ASP*, .NET*

Цель урока: Изучить способ авторизации через Cookie, использование стандартных атрибутов доступа к контроллеру и методу контроллера. Использование IPrincipal. Создание собственного модуля (IHttpModule) и собственного фильтра IActionFilter.

Небольшое отступление: На самом деле в asp.net mvc все учебники рекомендуют пользоваться уже придуманной системой авторизации, которая называется AspNetMembershipProvider, она была описана в статьеhttp://habrahabr.ru/post/142711/ (сейчас доступ уже закрыт), но обьяснено это с точки зрения «нажимай и не понимай, что там внутри». При первом знакомстве с asp.net mvc меня это смутило. Далее, в этой статьеhttp://habrahabr.ru/post/143024/ — сказано, что пользоваться этим провайдером – нельзя. И я согласен с этим. Здесь же, мы достаточно глубоко изучаем всякие хитрые asp.net mvc стандартные приемы, так что это один из основных уроков.

Кукисы

Кукисы – это часть информации, отсылаемая сервером браузеру, которую браузер возвращает обратно серверу вместе с каждым (почти каждым) запросом.

Сервер в заголовок ответа пишет:

6HW &RRNLH YDOXH>H[SLUHV GDWH@>GRPDLQ GRPDLQ@>SDWK SDWK@>VHFXUH@

Например:

+773 2. &RQWHQW W\SH WH[W KWPO 6HW &RRNLH QDPH YDOXH

6HW &RRNLH QDPH YDOXH ([SLUHV :HG-XQ *07

Браузер (если не истекло время действия кукиса) при каждом запросе:

*(7VSHF KWPO+773

+RVW ZZZ H[DPSOH RUJ

&RRNLH QDPH YDOXH QDPH YDOXH

$FFHSW

Устанавливаем cookie (/Areas/Default/Controllers/HomeController.cs):

SXEOLF $FWLRQ5HVXOW,QGH[

^

YDUFRRNLH QHZ+WWS&RRNLH

^

1DPH WHVWBFRRNLH

9DOXH 'DWH7LPH 1RZ 7R6WULQJGG 00 \\\\

([SLUHV 'DWH7LPH 1RZ$GG0LQXWHV

`

5HVSRQVH 6HW&RRNLH FRRNLH

UHWXUQ9LHZ

`

В Chrome проверяем установку:

Для получения кукисов:

YDUFRRNLH 5HTXHVW &RRNLHV>WHVWBFRRNLH@

Делаем точку остановки и проверяем:

Примечание: подробнее можно изучить кукисы по следующей ссылке: http://www.nczonline.net/blog/2009/05/05/http­cookies­explained/

Авторизация

В нашем случае авторизация будет основана на использовании кукисов. Для этого изучим следующие положения:

FormsAuthenticationTicket – мы воспользуемся этим классом, чтобы хранить данные авторизации в зашифрованном виде

Нужно реализовать интерфейс IPrincipal и установить в+WWS&RQWH[W 8VHU для проверки ролей и ,,GHQWLW\ интерфейса.

Для интерфейса IIdentity сделать реализацию

Вывести в BaseController в свойство CurrentUser значение пользователя, который сейчас залогинен.

Приступим.

Создадим интерфейс IAuthentication и его реализацию CustomAuthentication (/Global/Auth/IAuthentication.cs):

SXEOLF LQWHUIDFH ,$XWKHQWLFDWLRQ

^

VXPPDU\!

Ʉɨɧɟɤɫɬ ɬɭɬ ɦɵ ɩɨɥɭɱɚɟɦ ɞɨɫɬɭɩ ɤ ɡɚɩɪɨɫɭ ɢ ɤɭɤɢɫɚɦ

VXPPDU\!

+WWS&RQWH[W +WWS&RQWH[W ^JHW VHW`

8VHU/RJLQ VWULQJORJLQVWULQJSDVVZRUGERROLV3HUVLVWHQW

8VHU/RJLQ VWULQJORJLQ

YRLG /RJ2XW

,3ULQFLSDO &XUUHQW8VHU ^JHW`

`

Реализация (/Global/Auth/CustomAuthentication.cs):

SXEOLF FODVV &XVWRP$XWKHQWLFDWLRQ ,$XWKHQWLFDWLRQ

^

SULYDWH VWDWLF1/RJ /RJJHU ORJJHU 1/RJ /RJ0DQDJHU *HW&XUUHQW&ODVV/RJJHU

SULYDWH FRQVW VWULQJFRRNLH1DPH BB$87+B&22.,(

SXEOLF+WWS&RQWH[W +WWS&RQWH[W ^JHW VHW`

>,QMHFW@

SXEOLF,5HSRVLWRU\ 5HSRVLWRU\ ^JHW VHW`

UHJLRQ ,$XWKHQWLFDWLRQ 0HPEHUV

SXEOLF8VHU/RJLQ VWULQJXVHU1DPHVWULQJ3DVVZRUGERROLV3HUVLVWHQW

^

8VHU UHW8VHU 5HSRVLWRU\ /RJLQ XVHU1DPH 3DVVZRUG

LIUHW8VHU QXOO

^

&UHDWH&RRNLH XVHU1DPH LV3HUVLVWHQW

`

UHWXUQUHW8VHU

`

SXEOLF8VHU/RJLQ VWULQJXVHU1DPH

^

8VHU UHW8VHU 5HSRVLWRU\ 8VHUV )LUVW2U'HIDXOW S !VWULQJ&RPSDUH S (PDLO XVHU1DPH WUXH

LIUHW8VHU QXOO

^

&UHDWH&RRNLH XVHU1DPH

`

UHWXUQUHW8VHU

`

SULYDWH YRLG &UHDWH&RRNLH VWULQJXVHU1DPHERROLV3HUVLVWHQW IDOVH

^

YDUWLFNHW QHZ)RUPV$XWKHQWLFDWLRQ7LFNHW

XVHU1DPH

'DWH7LPH 1RZ

'DWH7LPH 1RZ$GG )RUPV$XWKHQWLFDWLRQ 7LPHRXW

LV3HUVLVWHQW

VWULQJ(PSW\

)RUPV$XWKHQWLFDWLRQ )RUPV&RRNLH3DWK

(QFU\SW WKH WLFNHW

YDUHQF7LFNHW )RUPV$XWKHQWLFDWLRQ (QFU\SW WLFNHW

&UHDWH WKH FRRNLH

YDU $XWK&RRNLH QHZ+WWS&RRNLH FRRNLH1DPH

^

9DOXH HQF7LFNHW

([SLUHV 'DWH7LPH 1RZ$GG )RUPV$XWKHQWLFDWLRQ 7LPHRXW

`

+WWS&RQWH[W 5HVSRQVH &RRNLHV 6HW$XWK&RRNLH

`

SXEOLF YRLG /RJ2XW

^

YDUKWWS&RRNLH +WWS&RQWH[W 5HVSRQVH &RRNLHV>FRRNLH1DPH@

LIKWWS&RRNLH QXOO

^

KWWS&RRNLH 9DOXH VWULQJ(PSW\

`

`

SULYDWH,3ULQFLSDO BFXUUHQW8VHU

SXEOLF,3ULQFLSDO &XUUHQW8VHU

^

JHW

^

LIBFXUUHQW8VHU QXOO

^

WU\

^

+WWS&RRNLH DXWK&RRNLH +WWS&RQWH[W 5HTXHVW &RRNLHV *HW FRRNLH1DPH

LIDXWK&RRNLH QXOO VWULQJ,V1XOO2U(PSW\ DXWK&RRNLH 9DOXH

^

YDUWLFNHW )RUPV$XWKHQWLFDWLRQ 'HFU\SW DXWK&RRNLH 9DOXH

BFXUUHQW8VHU QHZ8VHU3URYLGHU WLFNHW 1DPH 5HSRVLWRU\

`

HOVH

^

BFXUUHQW8VHU QHZ8VHU3URYLGHUQXOO QXOO

`

`

FDWFK([FHSWLRQ H[

^

ORJJHU (UURU)DLOHG DXWKHQWLFDWLRQH[ 0HVVDJH

BFXUUHQW8VHU QHZ8VHU3URYLGHUQXOO QXOO

`

`

UHWXUQBFXUUHQW8VHU

`

`

HQGUHJLRQ

`

Суть сводится к следующему, мы, при инициализации запроса, получаем доступ к +WWS&RQWH[W 5HTXHVW &RRNLHV и инициализируем 8VHU3URYLGHU:

YDUWLFNHW )RUPV$XWKHQWLFDWLRQ 'HFU\SW DXWK&RRNLH 9DOXH

BFXUUHQW8VHU QHZ8VHU3URYLGHU WLFNHW 1DPH 5HSRVLWRU\

Для авторизации в IRepository добавлен новый метод IRepository.Login. Реализация в

SqlRepository:

SXEOLF8VHU/RJLQ VWULQJHPDLOVWULQJSDVVZRUG

^

UHWXUQ'E 8VHUV )LUVW2U'HIDXOW S !VWULQJ&RPSDUH S (PDLO HPDLOWUXH S 3D VVZRUG SDVVZRUG

`

UserProvider, собственно, реализует интерфейс IPrincipal (в котором есть проверка ролей и доступ к IIdentity).

Рассмотрим класс UserProvider (/Global/Auth/UserProvider.cs):

SXEOLF FODVV 8VHU3URYLGHU ,3ULQFLSDO

^

SULYDWH8VHU,QGHQWLW\ XVHU,GHQWLW\ ^JHW VHW`

UHJLRQ ,3ULQFLSDO 0HPEHUV

SXEOLF,,GHQWLW\ ,GHQWLW\

^

JHW

^

UHWXUQXVHU,GHQWLW\

`

`

SXEOLF ERRO ,V,Q5ROH VWULQJUROH

^

LIXVHU,GHQWLW\ 8VHU QXOO

^

UHWXUQ IDOVH

`

UHWXUQXVHU,GHQWLW\ 8VHU ,Q5ROHV UROH

`

HQGUHJLRQ

SXEOLF 8VHU3URYLGHU VWULQJQDPH ,5HSRVLWRU\ UHSRVLWRU\

^

XVHU,GHQWLW\ QHZ8VHU,QGHQWLW\

XVHU,GHQWLW\ ,QLW QDPH UHSRVLWRU\

`

SXEOLF RYHUULGH VWULQJ 7R6WULQJ

^

UHWXUQXVHU,GHQWLW\ 1DPH

`

Наш 8VHU3URYLGHU знает про то, что его ,,GHQWLW\ классом есть8VHU,GHQWLW\, а поэтому знает про класс 8VHU, внутри которого мы реализуем метод ,Q5ROHV UROH:

SXEOLF ERRO ,Q5ROHV VWULQJUROHV

^

LI VWULQJ,V1XOO2U:KLWH6SDFH UROHV

^

UHWXUQ IDOVH

`

YDUUROHV$UUD\ UROHV 6SOLWQHZ>@ ^ ` 6WULQJ6SOLW2SWLRQV 5HPRYH(PSW\(QWULHV

IRUHDFK YDUUROHLQUROHV$UUD\

^

YDUKDV5ROH 8VHU5ROHV$Q\ S !VWULQJ&RPSDUH S 5ROH &RGH UROHWUXH

LIKDV5ROH

^

UHWXUQ WUXH

`

`

UHWXUQ IDOVH

`

В метод ,Q5ROHV мы ожидаем, что придет запрос о ролях, которые допущены к ресурсу, разделенные запятой. Т.е., например, “admin,moderator,editor”, если хотя бы одна из ролей есть у нашего 8VHU – то возвращаем зачение «истина» (доступ есть). Сравниваем по полю Role.Code,

а не Role.Name.

Рассмотрим класс UserIdentity (/Global/Auth/UserIdentity.cs):

SXEOLF FODVV 8VHU,QGHQWLW\ ,,GHQWLW\

^

SXEOLF8VHU 8VHU ^JHW VHW`

SXEOLF VWULQJ $XWKHQWLFDWLRQ7\SH

^

JHW

^

UHWXUQ W\SHRI8VHU 7R6WULQJ

`

`

SXEOLF ERRO,V$XWKHQWLFDWHG

^

JHW

^

UHWXUQ8VHU QXOO

`

`

SXEOLF VWULQJ1DPH

^

JHW

^

LI8VHU QXOO

^

UHWXUQ8VHU (PDLO

`

ɢɧɚɱɟ ɚɧɨɧɢɦ

UHWXUQ DQRQ\P

`

`

SXEOLF YRLG ,QLW VWULQJHPDLO ,5HSRVLWRU\ UHSRVLWRU\

^

LI VWULQJ,V1XOO2U(PSW\ HPDLO

^

8VHU UHSRVLWRU\ *HW8VHU HPDLO

`

`

`

В ,5HSRVLWRU\ добавляем новый метод *HW8VHU HPDLO. Реализация для6TO5HSRVLWRU\ *HW8VHU (LessonProject.Model:/SqlRepository/User.cs):

SXEOLF8VHU*HW8VHU VWULQJHPDLO

^

UHWXUQ'E 8VHUV )LUVW2U'HIDXOW S !VWULQJ&RPSDUH S (PDLO HPDLOWUXH

`

Почти все готово. Выведем CurrentUser в BaseController:

>,QMHFW@

SXEOLF,$XWKHQWLFDWLRQ$XWK ^JHW VHW`

SXEOLF8VHU &XUUHQW8VHU

^

JHW

^

UHWXUQ8VHU,QGHQWLW\$XWK &XUUHQW8VHU ,GHQWLW\ 8VHU

`

`

Да, это не очень правильно, так как здесь присутствует сильное связывание. Поэтому сделаем так, введем еще один интерфейс ,8VHU3URYLGHU, из которого мы будем требовать вернуть нам авторизованного 8VHU:

SXEOLF LQWHUIDFH ,8VHU3URYLGHU

^

8VHU 8VHU ^JHW VHW`

`

«

SXEOLF FODVV 8VHU,QGHQWLW\ ,,GHQWLW\ ,8VHU3URYLGHU

^

VXPPDU\!

Ɍɟɤɳɢɣ ɩɨɥɶɡɨɜɚɬɟɥɶ

VXPPDU\!

SXEOLF8VHU 8VHU ^JHW VHW`

«

>,QMHFW@ SXEOLF,$XWKHQWLFDWLRQ$XWK ^JHW VHW`

SXEOLF8VHU &XUUHQW8VHU

^

JHW

^

UHWXUQ,8VHU3URYLGHU$XWK &XUUHQW8VHU ,GHQWLW\ 8VHU

`

`

А теперь попробуем инициализировать это всё.

Вначале добавим наш IAuthentication + CustomAuthentication в регистрацию к Ninject (/App_Start/NinjectWebCommon.cs):

NHUQHO %LQG ,$XWKHQWLFDWLRQ! 7R &XVWRP$XWKHQWLFDWLRQ! ,Q5HTXHVW6FRSH

Потом создадим модуль, который будет на событие AuthenticateRequest совершать действие авторизации:

SXEOLF FODVV $XWK+WWS0RGXOH ,+WWS0RGXOH

^

SXEOLF YRLG ,QLW+WWS$SSOLFDWLRQ FRQWH[W

^

FRQWH[W$XWKHQWLFDWH5HTXHVW QHZ(YHQW+DQGOHUWKLV $XWKHQWLFDWH

`

SULYDWH YRLG $XWKHQWLFDWH2EMHFW VRXUFH (YHQW$UJV H

^

+WWS$SSOLFDWLRQ DSS +WWS$SSOLFDWLRQ VRXUFH

+WWS&RQWH[W FRQWH[W DSS &RQWH[W

YDUDXWK 'HSHQGHQF\5HVROYHU &XUUHQW *HW6HUYLFH ,$XWKHQWLFDWLRQ!

DXWK +WWS&RQWH[W FRQWH[W

FRQWH[W 8VHU DXWK &XUUHQW8VHU

`

SXEOLF YRLG 'LVSRVH

^

`

`

Соседние файлы в папке ASP.NET MVC Урок 1-F