简体   繁体   English

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

[英]Custom Authorization filter in ASP.NET MVC 5?

In ASP.NET MVC 5 we can use [Authorize] attribute to check authorization and limit access to some actions\\pages. 在ASP.NET MVC 5中,我们可以使用[Authorize]属性来检查授权并限制对某些actions \\ pages的访问。 I wonder how can I modify this attribute - authorization should be checked after some period of time? 我想知道如何修改这个属性 - 应该在一段时间后检查授权? For instance, let unauthorized user to see the page during 10 minutes and then block access . 例如,让未经授权的用户在10分钟内看到该页面然后阻止访问

Updated : it is seems that my question wasn't clear so I bolded the problem. 更新:似乎我的问题不明确所以我加粗了问题。 I need to count time each unauthorized user spent on the site and then block him after N minutes. 我需要计算每个未经授权的用户在网站上花费的时间,然后在N分钟后阻止他。

You may implement a custom authorization for allowing anonymous browsing during a limited amount of time like this: 您可以实施自定义授权,允许在有限的时间内进行匿名浏览,如下所示:

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;
            }
        }
    }
}

Then, use it as a global filter if it suits you, like this: 然后,如果它适合您,请将其用作全局过滤器,如下所示:

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

And do not forget to decorate your controllers or actions with AllowAnonymousAttribute : 并且不要忘记使用AllowAnonymousAttribute来装饰您的控制器或操作:

[AllowAnonymous]
public class YourController
{
}

Or 要么

public class YourController
{
    [AllowAnonymous]
    public ActionResult YourAction()
    {
    }
}

You may also put your custom authorize attribute directly on controllers or actions if defining it globally does not suit you: 您也可以将自定义授权属性直接放在控制器或操作上,如果全局定义它不适合您:

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

Please note this implementation does not secure the anonymous timeout. 请注意,此实现不保护匿名超时。 A hacker may overcome it and browse anonymously as long as he wishes. 只要他愿意,黑客就可以克服它并匿名浏览。 Browser tools allow for cookie deletion, so it is easy to start with a fresh timeout. 浏览器工具允许删除cookie,因此很容易以新的超时启动。
My example also just set a session cookie, which will be gone by closing/re-opening the browser. 我的例子也只是设置了一个会话cookie,关闭/重新打开浏览器就会消失。 Of course using another browser or device will allow for another 10 minutes of usage. 当然,使用其他浏览器或设备将允许另外10分钟的使用。

Securing an anonymous timeout is quite hard, since your user is anonymous. 保护匿名超时非常困难,因为您的用户是匿名的。 You may try to identify your anonymous users from their technical characteristics and then track their timeouts server side. 您可以尝试从其技术特征中识别您的匿名用户,然后跟踪他们的超时服务器端。
But you will probably run into many issues: corporate users browsing with the same IP address, or switching between different IP because they do not have a single Internet connection, ... 但是你可能会遇到很多问题:企业用户使用相同的IP地址浏览,或者在不同的IP之间切换,因为他们没有单一的Internet连接,...

Something like this? 像这样的东西? Create your own attribute and override the default with your own code. 创建自己的属性并使用您自己的代码覆盖默认值。

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

        //your code here
    }
}

Then decorate your controllers/actions with [CustomAuthAttribute] 然后用[CustomAuthAttribute]装饰你的控制器/动作

Below I have listed some examples that where and why to use AuthorizeAttribute 下面我列举了一些使用AuthorizeAttribute的地点和原因的示例

1.Check authorization and limit access to actions. 1.检查授权并限制对操作的访问。

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.Check authorization and limit access to controller. 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
   {
   }

I think that the Authorize attribute is designed to facilitate the authorizing process. 我认为Authorize属性旨在促进授权过程。 If you want to allow an anonymous user to view your site and block access after a while, consider some client side scripting. 如果您希望允许匿名用户在一段时间后查看您的站点并阻止访问,请考虑一些客户端脚本。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM