ASP.NET MVC 5中的自定义授权过滤器?
在ASP.NET MVC 5中,我们可以使用[Authorize]
属性来检查授权并限制对某些actions \ pages的访问。 我想知道如何修改这个属性 - 授权应该在一段时间后被检查? 例如,让未经授权的用户在10分钟内看到页面,然后阻止访问。ASP.NET MVC 5中的自定义授权过滤器?
更新:似乎我的问题并不清楚,所以我粗暴的问题。我需要计算每个未经授权的用户在网站上花费的时间,然后在N分钟后阻止他。
像这样的东西?使用您自己的代码创建您自己的属性并覆盖默认值。
public class CustomAuthAttribute : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
//your code here
}
}
下面我列出一些例子,在哪里以及为何使用AuthorizeAttribute
1,检查授权和限制访问行为与[CustomAuthAttribute]
然后装点你的控制器/行动。
Example :
// Restrict unauthorized access:
[Authorize]
public ActionResult YourActionView()
{
return View();
}
// Restrict by user:
[Authorize(Users = "prashant,lua")]
public ActionResult YourActionView()
{
return View();
}
// Restrict by role:
[Authorize(Roles="Administrators")]
public ActionResult YourActionView()
{
return View();
}
2.检查授权并限制对控制器的访问。
// Restrict unauthorized access:
[Authorize]
public class ValuesController : ApiController
{
}
// Restrict by user:
[Authorize(Users="Prashant,Lua")]
public class ValuesController : ApiController
{
}
// Restrict by role:
[Authorize(Roles="Administrators")]
public class ValuesController : ApiController
{
}
我认为Authorize属性是为了方便授权过程而设计的。如果您想允许匿名用户在一段时间后查看您的站点并阻止访问,请考虑一些客户端脚本。
您可以实现自定义授权的时间这样的量有限时,允许匿名浏览:
public class AuthorizeAttributeWithAnonTimeoutAttribute : AuthorizeAttribute
{
public int? AnonymousMinutesTimeout { get; set; }
public override void OnAuthorization(AuthorizationContext filterContext)
{
// Let default handling occurs
base.OnAuthorization(filterContext);
// If result is set, authorization has already been denied,
// nothing more to do.
if (filterContext.Result as HttpUnauthorizedResult != null)
return;
var isAnonAllowed = filterContext.ActionDescriptor.IsDefined(
typeof(AllowAnonymousAttribute), true) ||
filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(
typeof(AllowAnonymousAttribute), true);
if (isAnonAllowed && AnonymousMinutesTimeout.HasValue &&
// Not authorized
!AuthorizeCore(filterContext.HttpContext))
{
const string visitStartCookieName = "visitStartCookie";
const string visitStartDateFormat = "yyyyMMddhhmmss";
var visitStartCookie = filterContext.HttpContext.Request
.Cookies[visitStartCookieName];
var now = DateTime.UtcNow;
DateTime visitStartDate;
var visitStartCookieValid = visitStartCookie != null &&
DateTime.TryParseExact(visitStartCookie.Value,
visitStartDateFormat, null, DateTimeStyles.AssumeUniversal,
out visitStartDate);
if (!visitStartCookieValid)
{
visitStartDate = now;
filterContext.HttpContext.Response.Cookies.Add(
// Session cookie.
new HttpCookie
{
Name = "visitStartCookie",
Value = now.ToString(visitStartDateFormat)
});
}
if (visitStartDate.AddMinutes(AnonymousMinutesTimeout.Value) < now)
{
// Anonymous visit timed out
HandleUnauthorizedRequest(filterContext);
return;
}
}
}
}
然后,如果它适合你,像这样把它作为一个全球性的过滤器:
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(
new AuthorizeAttributeWithAnonTimeoutAttribute
{
// By example, 10 minutes
AnonymousMinutesTimeout = 10
});
// Your other filters
...
}
而且不要忘了AllowAnonymousAttribute来装饰你的控制器或动作:
[AllowAnonymous]
public class YourController
{
}
或者
public class YourController
{
[AllowAnonymous]
public ActionResult YourAction()
{
}
}
,您也可以直接把你的自定义授权属性的控制器或动作,如果定义在全球它不适合你:
// By example, 10 minutes anonymous browsing allowed.
[AuthorizeAttributeWithAnonTimeout(AnonymousMinutesTimeout = 10)]
public class YourController
{
}
请注意,这种做法不保证匿名超时。只要他愿意,黑客可以克服它并匿名浏览。浏览器工具允许删除cookie,因此很容易以新的超时启动。
确保匿名超时非常困难,因为您的用户是匿名的。您可能会尝试识别您的匿名用户,然后跟踪其超时服务器端。
但是,您可能会遇到很多问题:企业用户使用相同的IP地址浏览,或在不同的IP之间切换,因为它们没有单一的Internet连接,...
所以,你确实希望'[AllowAnonymous]',但只限于每次访问有限的时间,站点范围内。 –