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