В настоящее время я работаю над небольшим простым проектом. У меня есть список пользователей, хранящихся в базе данных:
Id (uniqueidentifier primary key), FirstName(varchar), LastName(varchar), PhoneNo(varchar), DomainAC(varchar)
Я использую ASP.net MVC для создания страницы со следующими простыми функциями:
Отобразите все данные о пользователе на странице – что я сделал, используя следующий код, сгенерированный представлением, созданным с помощью функции Index для ModelController, подключенной к моей базе данных:
<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<IEnumerable<Proj.Models.Employee>>" %>
<!DOCTYPE html>
<html>
<head runat="server">
<meta name="viewport" content="width=device-width" />
<title>Index</title>
</head>
<body>
<p>
<%: Html.ActionLink("Create New", "Create") %>
</p>
<table>
<tr>
<th>
<%: Html.DisplayNameFor(model => model.LastName) %>
</th>
<th>
<%: Html.DisplayNameFor(model => model.PhoneNo) %>
</th>
<th>
<%: Html.DisplayNameFor(model => model.DomainAC) %>
</th>
<th>
<%: Html.DisplayNameFor(model => model.FirstName) %>
</th>
<th></th>
</tr>
<% foreach (var item in Model) { %>
<tr>
<td>
<%: Html.DisplayFor(modelItem => item.LastName) %>
</td>
<td>
<%: Html.DisplayFor(modelItem => item.PhoneNo) %>
</td>
<td>
<%: Html.DisplayFor(modelItem => item.DomainAC) %>
</td>
<td>
<%: Html.DisplayFor(modelItem => item.FirstName) %>
</td>
<td>
<%: Html.ActionLink("Edit", "Edit", new { id=item.Id }) %> |
<%: Html.ActionLink("Details", "Details", new { id=item.Id }) %> |
<%: Html.ActionLink("Delete", "Delete", new { id=item.Id }) %>
</td>
</tr>
<% } %>
</table>
</body>
</html>
Это отображает голую страницу HTML, показывающую всех пользователей в голом столе. Существуют кнопки create/edit/delete; но они ничего не делают.
То, что я хотел бы сделать, просто для каждой строки
if(DomainAC == currently logged in Domain AC || currently logged in Domain AC is admin)
Allow user to edit/update details.
После некоторого расследования я думаю, что мне нужно создать пользовательский контроллер, который будет читать, с кем вы в настоящее время вошли в систему, и показывает кнопку редактирования, когда строка, возвращаемая DB ==, в настоящее время вошедшим в систему пользователем.
[Authorize(Users = @Context.User.Identity.Name)]
public ActionResult CurrentUser()
{
ViewBag.Message = "You are the logged in user";
return View();
}
[Authorize(Roles = @"DOMAIN\Administrators")]
public ActionResult Admins()
{
ViewBag.Message = "Your are admin.";
return View();
}
Вам нужно использовать собственный атрибут:
public class DomainACUserAttribute : AuthorizeAttribute
{
private UnitOfWork _unitOfWork = new UnitOfWork();
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
var isAuthorized = false;
var username = httpContext.User.Identity.Name;
// Some code to find the user in the database...
var user = _unitOfWork.EmployeeRepository.Find(username);
if(user != null)
{
isAuthorized = true;
}
return isAuthorized;
}
public override void OnAuthorization(AuthorizationContext filterContext)
{
if (filterContext == null)
{
throw new ArgumentNullException("filterContext");
}
if (AuthorizeCore(filterContext.HttpContext))
{
SetCachePolicy(filterContext);
}
else
{
// If not authorized, open the Unauthorized page...
filterContext.Result = new ViewResult { ViewName = "Unauthorized" };
}
}
protected void SetCachePolicy(AuthorizationContext filterContext)
{
// ** IMPORTANT **
// Since we're performing authorization at the action level,
// the authorization code runs after the output caching module.
// In the worst case this could allow an authorized user
// to cause the page to be cached, then an unauthorized user would later
// be served the cached page. We work around this by telling proxies not to
// cache the sensitive page, then we hook our custom authorization code into
// the caching mechanism so that we have the final say on whether a page
// should be served from the cache.
HttpCachePolicyBase cachePolicy = filterContext.HttpContext.Response.Cache;
cachePolicy.SetProxyMaxAge(new TimeSpan(0));
cachePolicy.AddValidationCallback(CacheValidationHandler, null /* data */);
}
public void CacheValidationHandler(HttpContext context,
object data,
ref HttpValidationStatus validationStatus)
{
validationStatus = OnCacheAuthorization(new HttpContextWrapper(context));
}
}
Затем вы можете использовать этот атрибут для своих действий с контроллером, например:
[DomainACUser]
public ActionResults Edit()
{
// Some code...
}
Вы можете создать отдельный пользовательский атрибут только для админов. И используйте его для действий, которые должны быть доступны только админам.
Если вы хотите скрыть ссылки “Редактировать и удалить” у людей, которые не должны иметь к ним доступ, вы можете проверить права пользователя в своем контроллере и передать информацию в свой вид в ViewData следующим образом:
// Code to check if the user is admin...
if (User is Admin)
{
ViewData["DisplayEdit"] = true;
}
И в вашем представлении:
<td>
<% if ((bool)ViewData["DisplayEdit"]) { %>
<%: Html.ActionLink("Edit", "Edit", new { id=item.Id }) %>
<% } %>
</td>
Я думаю, что ваш лучший выбор – просто установить условные выражения прямо в ваше представление, а также вручную проверить разрешение на вашем контроллере:
<td>
<% if (User.IsInRole("Administrators") || User.Identity.Name == item.DomainAC) { %>
<%: Html.ActionLink("Edit", "Edit", new { id=item.Id }) %> |
<%: Html.ActionLink("Details", "Details", new { id=item.Id }) %> |
<%: Html.ActionLink("Delete", "Delete", new { id=item.Id }) %>
<% } %>
</td>
public ActionResult Edit(int id) {
var user = GetUserById(id);
if (!User.IsInRole("Administrators") && User.Identity.Name != user.DomainAC) {
// unauthorized
}
// authorized - continue
}