Ограничить доступ к веб-странице с помощью контроллеров

Вопрос:

В настоящее время я работаю над небольшим простым проектом. У меня есть список пользователей, хранящихся в базе данных:

Id (uniqueidentifier primary key), FirstName(varchar), LastName(varchar), PhoneNo(varchar), DomainAC(varchar)

Я использую ASP.net MVC для создания страницы со следующими простыми функциями:

http://img17.imageshack.us/img17/7285/difq.png

Отобразите все данные о пользователе на странице — что я сделал, используя следующий код, сгенерированный представлением, созданным с помощью функции 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>

Ответ №1

Я думаю, что ваш лучший выбор — просто установить условные выражения прямо в ваше представление, а также вручную проверить разрешение на вашем контроллере:

<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
}

Оцените статью
TechArks.Ru
Добавить комментарий