Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/340.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# MVC3应用程序中的只读用户权限,更改最少_C#_Asp.net Mvc 3_Architecture_Filter_Readonly - Fatal编程技术网

C# MVC3应用程序中的只读用户权限,更改最少

C# MVC3应用程序中的只读用户权限,更改最少,c#,asp.net-mvc-3,architecture,filter,readonly,C#,Asp.net Mvc 3,Architecture,Filter,Readonly,我的任务是为我们的ASP.NETMVC3应用程序创建一个只读用户。即,他们可以登录、查看所有数据,但不能更新任何数据 我读过很多关于身份验证的文章/框架,比如这篇:,或者,或者(还有一些其他的,我已经失去了到的链接) 大多数方法的问题在于,它们需要对域/应用程序进行剧烈的更改。我只有一天的时间来实现这个功能 我们有大约一百个控制器,每个控制器平均有4个动作(大部分是CRUD操作),不可能对每一个都进行检查。此外,很容易忘记在新代码中添加属性-引入bug 到目前为止,我提出了一个全局过滤器,它拒绝

我的任务是为我们的ASP.NETMVC3应用程序创建一个只读用户。即,他们可以登录、查看所有数据,但不能更新任何数据

我读过很多关于身份验证的文章/框架,比如这篇:,或者,或者(还有一些其他的,我已经失去了到的链接)

大多数方法的问题在于,它们需要对域/应用程序进行剧烈的更改。我只有一天的时间来实现这个功能

我们有大约一百个控制器,每个控制器平均有4个动作(大部分是CRUD操作),不可能对每一个都进行检查。此外,很容易忘记在新代码中添加属性-引入bug

到目前为止,我提出了一个全局过滤器,它拒绝只读用户的所有基于帖子的操作和名为“创建”的控制器操作:

public class ReadOnlyFilter : IActionFilter 
{

    public void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var currentUser = HttpContext.Current.User;
        if (currentUser == null || !currentUser.Identity.IsAuthenticated)
            return; // user is not logged in yet


        if (!currentUser.IsInRole("Readonly")) 
            return; // user is not read-only. Nothing to see here, move on!

        // Presume User is read-only from now on.


        // if action is of type post - deny
        if (filterContext.HttpContext.Request.HttpMethod.ToUpper() == "POST")
        {
            filterContext.HttpContext.Response.Redirect("~/ReadOnlyAccess");
        }

        // if action is "Create" - deny access
        if (filterContext.ActionDescriptor.ActionName == "Create")
        {
            filterContext.HttpContext.Response.Redirect("~/ReadOnlyAccess");
        }

        // if action is edit - check if Details action exits -> redirect to it.
        //TODO get this done ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

        return;
    }


    public void OnActionExecuted(ActionExecutedContext filterContext)
    {
        // blah! have to have this here for IActionFilter
    }
}
接下来,我计划为post操作(如更改密码/电子邮件)创建属性[AllowareAndonlyUser],并在过滤器中允许该操作进行

我想知道是否有更好的方法来做这种事情

更新:该应用程序不供公众使用。它在企业界用于跟踪人员、资产和其他无聊的数据


更新2:我似乎已经完成了这项任务。作为一个控制器完成,就像开始一样。完整的代码和一些说明。

您可以根据需要使用System.Web.Mvc.authorized属性。创建一个从AuthorizeAttribute派生的类,并重写AuthorizeCore和HandleUnauthorizedRequest方法。在AuthorizeCore中,您确定是否允许用户执行操作;在HandleUnauthorizedRequest中,您确定不允许用户执行操作时显示的内容(例如,显示“NotAllowed”视图)


创建自定义授权属性后,必须将该属性添加到所有应受自定义授权保护的控制器操作中。例如,所有POST方法。但是,如果有一个POST方法应该允许所有用户使用,您只需不将该属性添加到该控制器操作。

您必须对此进行一些调整,在有人告诉我之前,我100%意识到这是一个可怕的黑客行为。但它也非常有效,并且很快就得到了实施,这是当时最令人担忧的问题。当然,你会想通过一个观察者来做这件事

其中还有一些更新面板的东西需要删除,或者在需要时更改为jqueryajax响应结束挂钩或类似的东西

哦,这里有一个控制为只读用户运行它的方法:

if (isReadonly && !Page.ClientScript.IsClientScriptBlockRegistered("ReadonlyScriptController"))
{
this.Page.ClientScript.RegisterStartupScript(this.GetType(), 
  "ReadonlyScriptController", "<script>RunReadonlyScript();</script>");
}
if(isReadonly&&!Page.ClientScript.IsClientScriptBlockRegistered(“ReadonlyScriptController”))
{
this.Page.ClientScript.RegisterStartupScript(this.GetType(),
“ReadOnlyScript控制器”、“RunReadonlyScript();”;
}
脚本:

<script type="text/javascript" src="<%# Page.ResolveUrl("~/ClientScripts/jquery-1.4.2.min.js") %>"></script>
<script type="text/javascript">
    function RunReadonlyScript() {
        //Extend jquery selections to add some new functionality
        //namely, the ability to select elements based on the
        //text of the element.
        $.expr[':'].textEquals = function (a, i, m) {
            var match = $(a).text().match("^" + m[3] + "$");
            return match && match.length > 0;
        };
        //this function does all the readonly work
        var disableStuff = function () {

            //select all controls that accept input, save changes, open a popup, or change form state
            // ** customize this with your own elements **
            $('button, input:not(:hidden), textarea, select,
              a:textEquals("Clear Selection"), 
              a:textEquals("Add Message"), 
              a:textEquals("CCC EVAL"),
              a[id$="availLink"], 
              a[id$="lbtnDelete"], 
              a[id$="lbtnEdit"]')
                //disable input controls
                .attr('disabled', 'disabled')
                //remove onclick javascript
                .removeAttr('onclick')
                //remove all bound click events
                .unbind("click")
                //add a new click event that does nothing
                //this stops <a> links from working
                .click(function (e) {
                    e.preventDefault(); 
                    return false;
                });

            //zap some images with click events that we don't want enabled
            $('img[id$="imgCalendar1"], img[id$="imgDelete"]').hide();
        }
        //if we are loading the home page, don't disable things
        //or the user won't be able to use the search controls
        var urlParts = document.URL.split('/');
        var last2 = urlParts[urlParts.length - 2] + '/' + urlParts[urlParts.length - 1];
        if (last2 !== 'home/view') {
            //disable everything initially
            disableStuff();
            //setup a timer to re-disable everything once per second
            //some tab panels need this to stay disabled
            setInterval(disableStuff, 1000);
            //some pages re-enable controls after update panels complete
            //make sure to keep them disabled!
            Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(disableStuff);
            Sys.WebForms.PageRequestManager.getInstance().add_endRequest(disableStuff);
        }
    }
</script>

函数RunReadonlyScript(){
//扩展jquery选择以添加一些新功能
//也就是说,基于
//元素的文本。
$.expr[':'].textEquals=函数(a,i,m){
var match=$(a.text().match(“^”+m[3]+“$”);
返回match&&match.length>0;
};
//此函数完成所有只读工作
var disableStuff=函数(){
//选择所有接受输入、保存更改、打开弹出窗口或更改表单状态的控件
//**使用您自己的元素进行定制**
$('按钮,输入:不(:隐藏),文本区域,选择,
a:textEquals(“清除选择”),
a:textEquals(“添加消息”),
a:textEquals(“CCC评估”),
a[id$=“可用”],
a[id$=“lbtnDelete”],
[id$=“lbtnEdit”])
//禁用输入控件
.attr('disabled'、'disabled')
//删除onclick javascript
.removeAttr('onclick')
//删除所有绑定的单击事件
.unbind(“单击”)
//添加不执行任何操作的新单击事件
//这会阻止链接工作
。单击(功能(e){
e、 预防默认值();
返回false;
});
//使用我们不希望启用的单击事件清除某些图像
$('img[id$=“imgCalendar1”]、img[id$=“imgDelete”]).hide();
}
//如果我们正在加载主页,不要禁用它
//否则用户将无法使用搜索控件
var urlParts=document.URL.split('/');
var last2=urlParts[urlParts.length-2]+'/'+urlParts[urlParts.length-1];
如果(last2!=='home/view'){
//最初禁用所有内容
可禁用的东西();
//设置计时器以每秒重新禁用所有内容一次
//某些选项卡面板需要此选项才能保持禁用状态
设置间隔(禁用,1000);
//某些页面在更新面板完成后重新启用控件
//一定要让他们残疾!
Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(disableStuff);
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(disableStuff);
}
}

这将允许未登录用户发布帖子。另外,我不确定“POST”是否保证为大写。我们的应用程序只供登录用户使用。除了LoginController,世界上没有可用的控制器。那很好。这篇文章说得对。我会把它修好的-谢谢!我最近不得不在很短的时间内将一个旧的asp.net webforms应用程序转换为只读模式。我的解决方案是使用javascript/jquery禁用所有输入控件和非导航超链接,并删除所有单击/提交功能代码以防止回发。@asawyer是的,这会起作用。直到你得到一个用户