- PVSM.RU - https://www.pvsm.ru -
Приветствую.
Сегодня мне бы хотелось рассказать в совсем небольшом уроке (уровень скорее для очень начинающих), как можно достаточно быстро и легко настроить аутентификацию [1] пользователей, а так же авторизацию [2] при их доступе к некоторому функционалу на Вашем сайте, используя штатные средства фреймворка MVC(4).
Я сейчас пишу личный простенький сайт для учета и ведения расходов, доходов, напоминания о периодических платежах (жкх, кредиты, школа и т.п.) + аналитика (в основном диаграммы), поскольку меня и мою жену функциональность Google Docs устраивать перестала.
Соответственно, встал вопрос о том, как закрыть информацию, в данном случае финансового состояния семьи от посторонних глаз под аутентификацию а так же распределить роли доступа (авторизация) — что могут жена, ребенок, анонимные пользователи, а что может администратор глава семьи.
Я считаю, что пользователь уже создал хотя бы один простой сайт на данном фреймворке, например, воспользовавшись базовой инструкцией по созданию простого каталога Ваших фильмов на фреймворке MVC4 [3] (у меня ушло около 20 минут).
Или же изучая MVC по второй, очень хорошей и более сложной инструкцией, по созданию онлайн магазина продажи музыкальных альбомов [4], (она касается MVC3, но, тем не менее, изучение MVC я рекомендую начинать с данной инструкции).
В процессе изучения второй инструкции я натолкнулся на проблемы, связанные с тем, что некоторые вещи в MVC4 изменились, по сравнению с MVC3, и брать устаревший код контроллера от предыдущей модели фреймворка и модели считаю плохой идеей, поэтому решил разобраться с этой задачей.
При создании нового проекта MVC4 по умолчанию вверху, справа при открытии сайта есть небольшое меню из двух пунктов — «Регистрация» и «Выполнить вход».
«Активировать» и запустить на нашем сайте ролевую модель доступа с распределением функционала.
По умолчанию все, что нам надо, уже есть и работает, спасибо разработчикам, но кое что нам придется дописать самостоятельно.
У меня стоят привычные мне русскоязычные варианты Visual Studio 2012 Express, .Net 4.5, SQL 2012 и MVC4 (а так же TFS2012 Express. Всё это живет на Windows 2008R2), в случае установки у Вас английской локализации названия, пункты меню и другие элементы интерфейса будут называться по другому, поэтому я по максимуму абстрагировался от скриншотов экрана.
Я предпочитаю отделять данные приложения от авторизации, поэтому создал отдельную базу данных users,
<connectionStrings>
<add name="DefaultConnection" connectionString="Data Source=(LocalDb)v11.0;Initial Catalog=aspnet-MyMoney-2132141343;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|users.mdf" providerName="System.Data.SqlClient" />
<add name="payDBContext" connectionString="Data Source=(LocalDb)v11.0;Initial Catalog=aspnet-MyMoney-data;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|MyMoney.mdf" providerName="System.Data.SqlClient" />
</connectionStrings>
Немного подробнее:
В данном списке подключений у нас есть соединение по умолчанию «DefaultConnection», у нас оно будет использоваться только для хранения пользовательской информации, поэтому мы это менять не будем, все данные приложения будут храниться в другой базе данных, payDBContext.
В настройках DefaultConnection мы меняем:
У меня за работу с финансовой информацией отвечает несколько контроллеров, поэтому в описании каждого контроллера (можно закрыть или наоборот, открыть отдельные методы) надо вставить соответствующую настройку доступа:
[Authorize(Roles = "Admin")]
namespace MyMoney.Controllers
{
[Authorize(Roles = "Admin")]
public class catController : Controller
{
Или же вставить такую строку для входа в методы нескольких ролей
[Authorize(Roles = "Admin, User")]
Теперь я хочу в зависимости от роли пользователя немного изменить список меню.
@{
var menus = new[]
{
new { LinkText="На главную", ActionName="Index",ControllerName="Home",Roles="All" },
new { LinkText="О себе", ActionName="About",ControllerName="Home",Roles="All" },
new { LinkText="Контакты", ActionName="Contact",ControllerName="Home",Roles="All" },
new { LinkText="Финансы", ActionName="Index",ControllerName="payments",Roles="Admin,User" },
};
}
<ul id="menu">
@if (HttpContext.Current.User.Identity.IsAuthenticated)
{
String[] roles = Roles.GetRolesForUser();
var links = from item in menus
where item.Roles.Split(new String[] { "," }, StringSplitOptions.RemoveEmptyEntries)
.Any(x => roles.Contains(x) || x == "All")
select item;
foreach (var link in links)
{
@: <li> @Html.ActionLink(link.LinkText, link.ActionName,link.ControllerName)</li>
}
}
else{
var links = from item in menus
where item.Roles.Split(new String[]{","},StringSplitOptions.RemoveEmptyEntries)
.Any(x=>new String[]{"All","Anonymous"}.Contains(x))
select item;
foreach ( var link in links){
@: <li> @Html.ActionLink(link.LinkText, link.ActionName, link.ControllerName)</li>
}
}
</ul>
<section id="login">
@Html.Partial("_LoginPartial")
</section>
<nav>
<ul id="navlist">
<li class="first"><a href="@Url.Content("~")" id="current">Home</a></li>
<li><a href="@Url.Content("~/Store/")">Store</a></li>
<li>@{Html.RenderAction("CartSummary", "ShoppingCart");}</li>
<li><a href="@Url.Content("~/StoreManager/")">Admin</a></li>
</ul>
</nav>
и меняем блок
<nav> ... </nav>
на
<nav>
@Html.Partial("~/Views/Shared/_Menu.cshtml")
</nav>
@{
var menus = new[]
{
new { LinkText="Home", ActionName="Index",ControllerName="Home",Roles="All" },
new { LinkText="About", ActionName="About",ControllerName="Home",Roles="Anonymous" },
new { LinkText="Contact", ActionName="Contact",ControllerName="Home",Roles="Anonymous" },
new { LinkText="Добавить платёж", ActionName="Create",ControllerName="pay",Roles="Admin,User" },
new { LinkText="Просмотр платежей", ActionName="Index",ControllerName="pay",Roles="Admin,User" },
new { LinkText="Добавить категорию", ActionName="Create",ControllerName="cat",Roles="Admin" },
new { LinkText="Просмотр категорий", ActionName="Index",ControllerName="cat",Roles="Admin,User" },
new { LinkText="Добавить пользователя", ActionName="Create",ControllerName="user",Roles="Admin" },
new { LinkText="Просмотр пользователей", ActionName="Index",ControllerName="user",Roles="Admin" },
new { LinkText="Добавить тип", ActionName="Create",ControllerName="type",Roles="Admin" },
new { LinkText="Просмотр типов", ActionName="Index",ControllerName="type",Roles="Admin" },
//new { LinkText="", ActionName="",ControllerName="",Roles="Administrator" },
};
}
@{
ViewBag.Title = "Управление финансами";
}
<h2>Управление финансами</h2>
<p>Вы: @User.Identity.Name</p>
<p>Вы входите в группы:</p>
<table>
<tr>
@{ foreach (string item in Roles.GetRolesForUser())
{
<li>@item</li>
}
}
</tr>
</table>
<ul id="list">
@if (HttpContext.Current.User.Identity.IsAuthenticated)
{
String[] roles = Roles.GetRolesForUser();
var links = from item in menus
where item.Roles.Split(new String[] { "," }, StringSplitOptions.RemoveEmptyEntries)
.Any(x => roles.Contains(x) || x == "All")
select item;
foreach (var link in links)
{
@: <li> @Html.ActionLink(link.LinkText, link.ActionName, link.ControllerName)</li>
}
}
else
{
var links = from item in menus
where item.Roles.Split(new String[] { "," }, StringSplitOptions.RemoveEmptyEntries)
.Any(x => new String[] { "All", "Anonymous" }.Contains(x))
select item;
foreach (var link in links)
{
@: <li> @Html.ActionLink(link.LinkText, link.ActionName, link.ControllerName)</li>
}
}
</ul>
Теперь надо очистить, пересобрать приложение и можно запускать. Если зная ссылку на один из контроллеров, закрытых для анонимного входа, попробовать зайти — получите форму авторизации с последующим обратным переходом на страничку, которая являлась инициатором авторизации.
Выглядит это так:
Второе, о чем я сейчас думаю — надо в свою БД финансов привязать получение данных текущего авторизованного пользователя, т.к. сейчас в гугль докс приходится руками выбирать, кто был инициатором расхода/дохода — а вводить два раза информацию глупо. А в идеале — получать авторизацию и из Windows сессии, если броузер IE.
Да, за некоторые фрагменты кода меня, как начинающего надо больно бить по рукам, поэтому я с удовольствием приму поправки и улучшения данного кода.
Спасибо за внимание, надеюсь я кому-то помог.
Автор: foxmuldercp
Источник [5]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/web-razrabotka/18788
Ссылки в тексте:
[1] аутентификацию: http://ru.wikipedia.org/wiki/%D0%90%D1%83%D1%82%D0%B5%D0%BD%D1%82%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8F
[2] авторизацию: http://ru.wikipedia.org/wiki/%D0%90%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F
[3] воспользовавшись базовой инструкцией по созданию простого каталога Ваших фильмов на фреймворке MVC4: http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/intro-to-aspnet-mvc-4
[4] очень хорошей и более сложной инструкцией, по созданию онлайн магазина продажи музыкальных альбомов: http://www.asp.net/mvc/tutorials/mvc-music-store/mvc-music-store-part-1
[5] Источник: http://habrahabr.ru/post/156443/
Нажмите здесь для печати.