0

私は現在、小さくて単純なプロジェクトに取り組んでいます。次のようにデータベースに保存されたユーザーのリストがあります。

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

ASP.net MVC を使用して、次の単純な機能を持つページを作成しています。

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

ページにすべてのユーザーの詳細を表示します。これは、データベースにフックされた ModelController の Index 関数を使用して作成したビューによって生成された次のコードを使用して行いました。

<%@ 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 ページがレンダリングされ、すべてのユーザーが裸のテーブルに表示されます。作成/編集/削除ボタンがあります。しかし、彼らは何もしません。

私がやりたいことは、単純に、行ごとに

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();
    }
4

2 に答える 2

1

次のようなカスタム属性を使用する必要があります。

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>
于 2013-07-05T15:55:36.747 に答える
0

あなたの最善の策は、条件をビューに直接入れて、コントローラーの許可を手動でチェックすることだと思います。

<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
}
于 2013-07-05T15:38:52.400 に答える