ASP.NET MVC 5中的自定义授权过滤器?

Lua*_*eng 5 c# asp.net asp.net-mvc asp.net-mvc-5

在ASP.NET MVC 5中,我们可以使用[Authorize]attribute来检查授权并限制对某些actions\pages的访问.我想知道如何修改这个属性 - 应该在一段时间后检查授权? 例如,让未经授权的用户在10分钟内看到该页面然后阻止访问.

更新:似乎我的问题不明确所以我加粗了问题.我需要计算每个未经授权的用户在网站上花费的时间,然后在N分钟后阻止他.

Fré*_*ric 12

您可以实施自定义授权,允许在有限的时间内进行匿名浏览,如下所示:

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. (Need to set an expiry date if
                    // a "permanent" cookie is wished instead.)
                    new HttpCookie
                    {
                        Name = "visitStartCookie",
                        Value = now.ToString(visitStartDateFormat)
                    });
            }
            if (visitStartDate.AddMinutes(AnonymousMinutesTimeout.Value) < now)
            {
                // Anonymous visit timed out
                HandleUnauthorizedRequest(filterContext);
                return;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,如果它适合您,请将其用作全局过滤器,如下所示:

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(
        new AuthorizeAttributeWithAnonTimeoutAttribute
        {
            // By example, 10 minutes
            AnonymousMinutesTimeout = 10
        });
    // Your other filters
    ...
}
Run Code Online (Sandbox Code Playgroud)

并且不要忘记用以下内容装饰您的控制器或操作AllowAnonymousAttribute:

[AllowAnonymous]
public class YourController
{
}
Run Code Online (Sandbox Code Playgroud)

要么

public class YourController
{
    [AllowAnonymous]
    public ActionResult YourAction()
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

您也可以将自定义授权属性直接放在控制器或操作上,如果全局定义它不适合您:

// By example, 10 minutes anonymous browsing allowed.
[AuthorizeAttributeWithAnonTimeout(AnonymousMinutesTimeout = 10)]
public class YourController
{
}
Run Code Online (Sandbox Code Playgroud)

请注意,此实现不保护匿名超时.只要他愿意,黑客就可以克服它并匿名浏览.浏览器工具允许删除cookie,因此很容易以新的超时启动.
我的例子也只是设置了一个会话cookie,关闭/重新打开浏览器就会消失.当然,使用其他浏览器或设备将允许另外10分钟的使用.

保护匿名超时非常困难,因为您的用户是匿名的.您可以尝试从其技术特征中识别您的匿名用户,然后跟踪他们的超时服务器端.
但是你可能会遇到很多问题:企业用户使用相同的IP地址浏览,或者在不同的IP之间切换,因为他们没有单一的Internet连接,...


gar*_*thb 3

像这样的东西吗?创建您自己的属性并使用您自己的代码覆盖默认值。

public class CustomAuthAttribute : AuthorizeAttribute
{
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        base.OnAuthorization(filterContext);

        //your code here
    }
}
Run Code Online (Sandbox Code Playgroud)

然后用 [CustomAuthAttribute] 装饰你的控制器/动作