2009-01-23 42 views
56

Tôi có một dự án ASP.NET MVC chứa một lớp AdminController và đem lại cho tôi URL như thế này:Hạn chế truy cập đến một bộ điều khiển cụ thể theo địa chỉ IP trong ASP.NET MVC Beta

http://example.com/admin/AddCustomer

http://examle.com/Admin/ListCustomers

Tôi muốn định cấu hình máy chủ/ứng dụng để URI chứa /Admin chỉ có thể truy cập từ mạng 192.168.0.0/24 (tức là mạng LAN của chúng tôi)

Tôi muốn hạn chế bộ điều khiển này chỉ có thể truy cập được từ một số địa chỉ IP nhất định.

Trong WebForms,/admin/là một thư mục vật lý mà tôi có thể giới hạn trong IIS ... nhưng với MVC, tất nhiên, không có thư mục vật lý. Điều này có thể đạt được bằng cách sử dụng web.config hoặc các thuộc tính hay tôi cần chặn yêu cầu HTTP để đạt được điều này?

+0

Một câu hỏi tương tự có câu trả lời mà bạn tìm kiếm. .. http://stackoverflow.com/a/6108168/80161 –

Trả lời

76

Tôi biết đây là một câu hỏi cũ, nhưng tôi cần có chức năng này ngay hôm nay để tôi triển khai và nghĩ về việc đăng nó ở đây.

Sử dụng lớp IPList từ đây (http://www.codeproject.com/KB/IP/ipnumbers.aspx)

Bộ lọc thuộc tính FilterIPAttribute.cs:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using System.Web.Http; 
using System.Security.Principal; 
using System.Configuration; 

namespace Miscellaneous.Attributes.Controller 
{ 

    /// <summary> 
    /// Filter by IP address 
    /// </summary> 
    public class FilterIPAttribute : AuthorizeAttribute 
    { 

     #region Allowed 
     /// <summary> 
     /// Comma seperated string of allowable IPs. Example "10.2.5.41,192.168.0.22" 
     /// </summary> 
     /// <value></value> 
     public string AllowedSingleIPs { get; set; } 

     /// <summary> 
     /// Comma seperated string of allowable IPs with masks. Example "10.2.0.0;255.255.0.0,10.3.0.0;255.255.0.0" 
     /// </summary> 
     /// <value>The masked I ps.</value> 
     public string AllowedMaskedIPs { get; set; } 

     /// <summary> 
     /// Gets or sets the configuration key for allowed single IPs 
     /// </summary> 
     /// <value>The configuration key single I ps.</value> 
     public string ConfigurationKeyAllowedSingleIPs { get; set; } 

     /// <summary> 
     /// Gets or sets the configuration key allowed mmasked IPs 
     /// </summary> 
     /// <value>The configuration key masked I ps.</value> 
     public string ConfigurationKeyAllowedMaskedIPs { get; set; } 

     /// <summary> 
     /// List of allowed IPs 
     /// </summary> 
     IPList allowedIPListToCheck = new IPList(); 
     #endregion 

     #region Denied 
     /// <summary> 
     /// Comma seperated string of denied IPs. Example "10.2.5.41,192.168.0.22" 
     /// </summary> 
     /// <value></value> 
     public string DeniedSingleIPs { get; set; } 

     /// <summary> 
     /// Comma seperated string of denied IPs with masks. Example "10.2.0.0;255.255.0.0,10.3.0.0;255.255.0.0" 
     /// </summary> 
     /// <value>The masked I ps.</value> 
     public string DeniedMaskedIPs { get; set; } 


     /// <summary> 
     /// Gets or sets the configuration key for denied single IPs 
     /// </summary> 
     /// <value>The configuration key single I ps.</value> 
     public string ConfigurationKeyDeniedSingleIPs { get; set; } 

     /// <summary> 
     /// Gets or sets the configuration key for denied masked IPs 
     /// </summary> 
     /// <value>The configuration key masked I ps.</value> 
     public string ConfigurationKeyDeniedMaskedIPs { get; set; } 

     /// <summary> 
     /// List of denied IPs 
     /// </summary> 
     IPList deniedIPListToCheck = new IPList(); 
     #endregion 


     /// <summary> 
     /// Determines whether access to the core framework is authorized. 
     /// </summary> 
     /// <param name="actionContext">The HTTP context, which encapsulates all HTTP-specific information about an individual HTTP request.</param> 
     /// <returns> 
     /// true if access is authorized; otherwise, false. 
     /// </returns> 
     /// <exception cref="T:System.ArgumentNullException">The <paramref name="httpContext"/> parameter is null.</exception> 
     protected override bool IsAuthorized(HttpActionContext actionContext) 
     { 
      if (actionContext == null) 
       throw new ArgumentNullException("actionContext"); 

      string userIpAddress = ((HttpContextWrapper)actionContext.Request.Properties["MS_HttpContext"]).Request.UserHostName; 

      try 
      { 
       // Check that the IP is allowed to access 
       bool ipAllowed = CheckAllowedIPs(userIpAddress); 

       // Check that the IP is not denied to access 
       bool ipDenied = CheckDeniedIPs(userIpAddress);  

       // Only allowed if allowed and not denied 
       bool finallyAllowed = ipAllowed && !ipDenied; 

       return finallyAllowed; 
      } 
      catch (Exception e) 
      { 
       // Log the exception, probably something wrong with the configuration 
      } 

      return true; // if there was an exception, then we return true 
     } 

     /// <summary> 
     /// Checks the allowed IPs. 
     /// </summary> 
     /// <param name="userIpAddress">The user ip address.</param> 
     /// <returns></returns> 
     private bool CheckAllowedIPs(string userIpAddress) 
     { 
      // Populate the IPList with the Single IPs 
      if (!string.IsNullOrEmpty(AllowedSingleIPs)) 
      { 
       SplitAndAddSingleIPs(AllowedSingleIPs, allowedIPListToCheck); 
      } 

      // Populate the IPList with the Masked IPs 
      if (!string.IsNullOrEmpty(AllowedMaskedIPs)) 
      { 
       SplitAndAddMaskedIPs(AllowedMaskedIPs, allowedIPListToCheck); 
      } 

      // Check if there are more settings from the configuration (Web.config) 
      if (!string.IsNullOrEmpty(ConfigurationKeyAllowedSingleIPs)) 
      { 
       string configurationAllowedAdminSingleIPs = ConfigurationManager.AppSettings[ConfigurationKeyAllowedSingleIPs]; 
       if (!string.IsNullOrEmpty(configurationAllowedAdminSingleIPs)) 
       { 
        SplitAndAddSingleIPs(configurationAllowedAdminSingleIPs, allowedIPListToCheck); 
       } 
      } 

      if (!string.IsNullOrEmpty(ConfigurationKeyAllowedMaskedIPs)) 
      { 
       string configurationAllowedAdminMaskedIPs = ConfigurationManager.AppSettings[ConfigurationKeyAllowedMaskedIPs]; 
       if (!string.IsNullOrEmpty(configurationAllowedAdminMaskedIPs)) 
       { 
        SplitAndAddMaskedIPs(configurationAllowedAdminMaskedIPs, allowedIPListToCheck); 
       } 
      } 

      return allowedIPListToCheck.CheckNumber(userIpAddress); 
     } 

     /// <summary> 
     /// Checks the denied IPs. 
     /// </summary> 
     /// <param name="userIpAddress">The user ip address.</param> 
     /// <returns></returns> 
     private bool CheckDeniedIPs(string userIpAddress) 
     { 
      // Populate the IPList with the Single IPs 
      if (!string.IsNullOrEmpty(DeniedSingleIPs)) 
      { 
       SplitAndAddSingleIPs(DeniedSingleIPs, deniedIPListToCheck); 
      } 

      // Populate the IPList with the Masked IPs 
      if (!string.IsNullOrEmpty(DeniedMaskedIPs)) 
      { 
       SplitAndAddMaskedIPs(DeniedMaskedIPs, deniedIPListToCheck); 
      } 

      // Check if there are more settings from the configuration (Web.config) 
      if (!string.IsNullOrEmpty(ConfigurationKeyDeniedSingleIPs)) 
      { 
       string configurationDeniedAdminSingleIPs = ConfigurationManager.AppSettings[ConfigurationKeyDeniedSingleIPs]; 
       if (!string.IsNullOrEmpty(configurationDeniedAdminSingleIPs)) 
       { 
        SplitAndAddSingleIPs(configurationDeniedAdminSingleIPs, deniedIPListToCheck); 
       } 
      } 

      if (!string.IsNullOrEmpty(ConfigurationKeyDeniedMaskedIPs)) 
      { 
       string configurationDeniedAdminMaskedIPs = ConfigurationManager.AppSettings[ConfigurationKeyDeniedMaskedIPs]; 
       if (!string.IsNullOrEmpty(configurationDeniedAdminMaskedIPs)) 
       { 
        SplitAndAddMaskedIPs(configurationDeniedAdminMaskedIPs, deniedIPListToCheck); 
       } 
      } 

      return deniedIPListToCheck.CheckNumber(userIpAddress); 
     } 

     /// <summary> 
     /// Splits the incoming ip string of the format "IP,IP" example "10.2.0.0,10.3.0.0" and adds the result to the IPList 
     /// </summary> 
     /// <param name="ips">The ips.</param> 
     /// <param name="list">The list.</param> 
     private void SplitAndAddSingleIPs(string ips,IPList list) 
     { 
      var splitSingleIPs = ips.Split(','); 
      foreach (string ip in splitSingleIPs) 
       list.Add(ip); 
     } 

     /// <summary> 
     /// Splits the incoming ip string of the format "IP;MASK,IP;MASK" example "10.2.0.0;255.255.0.0,10.3.0.0;255.255.0.0" and adds the result to the IPList 
     /// </summary> 
     /// <param name="ips">The ips.</param> 
     /// <param name="list">The list.</param> 
     private void SplitAndAddMaskedIPs(string ips, IPList list) 
     { 
      var splitMaskedIPs = ips.Split(','); 
      foreach (string maskedIp in splitMaskedIPs) 
      { 
       var ipAndMask = maskedIp.Split(';'); 
       list.Add(ipAndMask[0], ipAndMask[1]); // IP;MASK 
      } 
     } 

     public override void OnAuthorization(AuthorizationContext filterContext) 
     { 
      base.OnAuthorization(filterContext); 
     } 
    } 
} 

Ví dụ sử dụng:

1. Trực tiếp chỉ định IP trong mã số

[FilterIP(
     AllowedSingleIPs="10.2.5.55,192.168.2.2", 
     AllowedMaskedIPs="10.2.0.0;255.255.0.0,192.168.2.0;255.255.255.0" 
    )] 
    public class HomeController { 
     // Some code here 
    } 

2. Hoặc, tải cấu hình từ Web.config

[FilterIP(
     ConfigurationKeyAllowedSingleIPs="AllowedAdminSingleIPs", 
     ConfigurationKeyAllowedMaskedIPs="AllowedAdminMaskedIPs", 
     ConfigurationKeyDeniedSingleIPs="DeniedAdminSingleIPs", 
     ConfigurationKeyDeniedMaskedIPs="DeniedAdminMaskedIPs" 
    )] 
    public class HomeController { 
     // Some code here 
    } 


<configuration> 
<appSettings> 
    <add key="AllowedAdminSingleIPs" value="localhost,127.0.0.1"/> <!-- Example "10.2.80.21,192.168.2.2" --> 
    <add key="AllowedAdminMaskedIPs" value="10.2.0.0;255.255.0.0"/> <!-- Example "10.2.0.0;255.255.0.0,192.168.2.0;255.255.255.0" --> 
    <add key="DeniedAdminSingleIPs" value=""/> <!-- Example "10.2.80.21,192.168.2.2" --> 
    <add key="DeniedAdminMaskedIPs" value=""/> <!-- Example "10.2.0.0;255.255.0.0,192.168.2.0;255.255.255.0" --> 
</appSettings> 
</configuration> 
+10

Cổ vũ rực rỡ. Tôi cũng đã chuyển sang ASP.NET Web API của bạn tại đây: https://gist.github.com/2028849. (IIS được lưu trữ chỉ vì nó vẫn còn yêu cầu HttpContext.Current. Tôi không chắc chắn làm thế nào để có được IP khách hàng có nguồn gốc từ HttpRequestMessage.) –

+0

Điều này dường như không hoạt động với địa chỉ IPv6, đó là một vấn đề bởi vì trong rất nhiều cấu hình địa chỉ ip localhost trở lại như :: 1 –

+0

Tôi biết đây là cũ, nhưng tôi phải thêm một cái gì đó ở đâu đó để làm việc này, tôi thêm chú thích vào bộ điều khiển tôi muốn bảo vệ IP như trong ví dụ bạn sử dụng, và nó Không lam gi cả. Bất kỳ IP nào vẫn có thể thực hiện các phương thức –

9

Bạn cần có quyền truy cập vào UserHostAddress trong đối tượng Yêu cầu trong bộ điều khiển của bạn để thực hiện hạn chế. Tôi khuyên bạn nên mở rộng AuthorizeAttribute và thêm các hạn chế địa chỉ IP vào nó để bạn có thể đơn giản trang trí mọi phương thức hoặc bộ điều khiển cần bảo vệ này.

+0

Đây là lớp IP tiện dụng có thể trợ giúp với việc lọc: http://www.codeproject.com/KB/IP/ipnumbers.aspx –

+0

@tvanfosson Bảo mật như thế nào điều này có bị giới hạn bởi IP không? Điều tôi muốn biết là nếu ai đó dễ dàng giả mạo một IP để bỏ qua tính năng bảo mật này. – Despertar

+0

@Despertar Vì phản hồi sẽ được gửi trở lại địa chỉ IP mà từ đó yêu cầu được thực hiện, nếu máy sở hữu địa chỉ IP nằm dưới sự kiểm soát và bảo mật của bạn, thì tôi nghĩ nó hoạt động khá tốt. Nó có thể thậm chí còn an toàn hơn khi được sử dụng kết hợp với địa chỉ cục bộ (không định tuyến). Tôi sẽ ít có khả năng sử dụng điều này để bảo mật quyền truy cập vào dữ liệu nhạy cảm với một hệ thống ngoài tầm kiểm soát của tôi. Trong những trường hợp đó, tôi có thể sử dụng nó cùng với một tên người dùng/mật khẩu hoặc khóa API, nếu thích hợp. – tvanfosson

1

Tôi cần một giải pháp cho vấn đề này trong MVC4 mà có thể xử lý IPv6 và dãy IP. Ngoài ra, tôi cần sử dụng danh sách trắng và đen để ủy quyền nhưng cũng sử dụng quy trình cấp phép thông thường khi IP không phải.

Đây là giải pháp tôi đến sau khi tham gia rất nhiều từ @sabbour và @Richard Szalay (How to check a input IP fall in a specific IP range) các bài đăng tuyệt vời vì vậy tôi đăng lại ở đây để mọi người có thể trợ giúp.

public class MagniAuthorizeAttribute : FilterAttribute, IAuthorizationFilter 
{ 

    #region Allowed 

    public bool IsPublic { get; set; } 
    /// <summary> 
    /// Comma seperated string of allowable IPs. Example "10.2.5.41,192.168.0.22" 
    /// </summary> 
    /// <value></value>   
    public string AllowedSingleIPs { get; set; } 

    /// <summary> 
    /// Comma seperated string of allowable IPs with masks. Example "10.2.0.0;255.255.0.0,10.3.0.0;255.255.0.0" 
    /// </summary> 
    /// <value>The masked I ps.</value> 
    public string AllowedIPRanges { get; set; } 

    /// <summary> 
    /// Gets or sets the configuration key for allowed single IPs 
    /// </summary> 
    /// <value>The configuration key single I ps.</value> 
    public string ConfigurationKeyAllowedSingleIPs { get; set; } 

    /// <summary> 
    /// Gets or sets the configuration key allowed mmasked IPs 
    /// </summary> 
    /// <value>The configuration key masked I ps.</value> 
    public string ConfigurationKeyAllowedMaskedIPs { get; set; } 

    #endregion 

    #region Denied 
    /// <summary> 
    /// Comma seperated string of denied IPs. Example "10.2.5.41,192.168.0.22" 
    /// </summary> 
    /// <value></value> 
    public string DeniedSingleIPs { get; set; } 

    /// <summary> 
    /// Comma seperated string of denied IPs with masks. Example "10.2.0.0;255.255.0.0,10.3.0.0;255.255.0.0" 
    /// </summary> 
    /// <value>The masked I ps.</value> 
    public string DeniedIPRanges { get; set; } 


    /// <summary> 
    /// Gets or sets the configuration key for denied single IPs 
    /// </summary> 
    /// <value>The configuration key single I ps.</value> 
    public string ConfigurationKeyDeniedSingleIPs { get; set; } 

    /// <summary> 
    /// Gets or sets the configuration key for denied masked IPs 
    /// </summary> 
    /// <value>The configuration key masked I ps.</value> 
    public string ConfigurationKeyDeniedMaskedIPs { get; set; } 

    #endregion 


    /// <summary> 
    /// Checks the allowed IPs. 
    /// </summary> 
    /// <param name="userIpAddress">The user ip address.</param> 
    /// <returns></returns> 
    private bool CheckAllowedIPs(IPAddress userIpAddress) 
    { 
     List<IPAddress> allowedIPsToCheck = new List<IPAddress>(); 
     List<IPAddressRange> allowedIPRangesToCheck = new List<IPAddressRange>(); 

     // Populate the IPList with the Single IPs 
     if (!string.IsNullOrEmpty(AllowedSingleIPs)) 
     { 
      SplitAndAddSingleIPs(AllowedSingleIPs, allowedIPsToCheck); 
     } 

     // Populate the IPList with the Masked IPs 
     if (!string.IsNullOrEmpty(AllowedIPRanges)) 
     { 
      SplitAndAddIPRanges(AllowedIPRanges, allowedIPRangesToCheck); 
     } 

     // Check if there are more settings from the configuration (Web.config) 
     if (!string.IsNullOrEmpty(ConfigurationKeyAllowedSingleIPs)) 
     { 
      string configurationAllowedAdminSingleIPs = ConfigurationManager.AppSettings[ConfigurationKeyAllowedSingleIPs]; 
      if (!string.IsNullOrEmpty(configurationAllowedAdminSingleIPs)) 
      { 
       SplitAndAddSingleIPs(configurationAllowedAdminSingleIPs, allowedIPsToCheck); 
      } 
     } 

     if (!string.IsNullOrEmpty(ConfigurationKeyAllowedMaskedIPs)) 
     { 
      string configurationAllowedAdminMaskedIPs = ConfigurationManager.AppSettings[ConfigurationKeyAllowedMaskedIPs]; 
      if (!string.IsNullOrEmpty(configurationAllowedAdminMaskedIPs)) 
      { 
       SplitAndAddIPRanges(configurationAllowedAdminMaskedIPs, allowedIPRangesToCheck); 
      } 
     } 

     return allowedIPsToCheck.Any(a => a.Equals(userIpAddress)) || allowedIPRangesToCheck.Any(a => a.IsInRange(userIpAddress)); 
    } 

    /// <summary> 
    /// Checks the denied IPs. 
    /// </summary> 
    /// <param name="userIpAddress">The user ip address.</param> 
    /// <returns></returns> 
    private bool CheckDeniedIPs(IPAddress userIpAddress) 
    { 
     List<IPAddress> deniedIPsToCheck = new List<IPAddress>(); 
     List<IPAddressRange> deniedIPRangesToCheck = new List<IPAddressRange>(); 

     // Populate the IPList with the Single IPs 
     if (!string.IsNullOrEmpty(DeniedSingleIPs)) 
     { 
      SplitAndAddSingleIPs(DeniedSingleIPs, deniedIPsToCheck); 
     } 

     // Populate the IPList with the Masked IPs 
     if (!string.IsNullOrEmpty(DeniedIPRanges)) 
     { 
      SplitAndAddIPRanges(DeniedIPRanges, deniedIPRangesToCheck); 
     } 

     // Check if there are more settings from the configuration (Web.config) 
     if (!string.IsNullOrEmpty(ConfigurationKeyDeniedSingleIPs)) 
     { 
      string configurationDeniedAdminSingleIPs = ConfigurationManager.AppSettings[ConfigurationKeyDeniedSingleIPs]; 
      if (!string.IsNullOrEmpty(configurationDeniedAdminSingleIPs)) 
      { 
       SplitAndAddSingleIPs(configurationDeniedAdminSingleIPs, deniedIPsToCheck); 
      } 
     } 

     if (!string.IsNullOrEmpty(ConfigurationKeyDeniedMaskedIPs)) 
     { 
      string configurationDeniedAdminMaskedIPs = ConfigurationManager.AppSettings[ConfigurationKeyDeniedMaskedIPs]; 
      if (!string.IsNullOrEmpty(configurationDeniedAdminMaskedIPs)) 
      { 
       SplitAndAddIPRanges(configurationDeniedAdminMaskedIPs, deniedIPRangesToCheck); 
      } 
     } 

     return deniedIPsToCheck.Any(a => a.Equals(userIpAddress)) || deniedIPRangesToCheck.Any(a => a.IsInRange(userIpAddress)); 
    } 

    /// <summary> 
    /// Splits the incoming ip string of the format "IP,IP" example "10.2.0.0,10.3.0.0" and adds the result to the IPAddress list 
    /// </summary> 
    /// <param name="ips">The ips.</param> 
    /// <param name="list">The list.</param> 
    private void SplitAndAddSingleIPs(string ips, List<IPAddress> list) 
    { 
     var splitSingleIPs = ips.Split(','); 
     IPAddress ip; 

     foreach (string ipString in splitSingleIPs) 
     { 
      if(IPAddress.TryParse(ipString, out ip)) 
       list.Add(ip); 
     } 
    } 

    /// <summary> 
    /// Splits the incoming ip ranges string of the format "IP-IP,IP-IP" example "10.2.0.0-10.2.255.255,10.3.0.0-10.3.255.255" and adds the result to the IPAddressRange list 
    /// </summary> 
    /// <param name="ips">The ips.</param> 
    /// <param name="list">The list.</param> 
    private void SplitAndAddIPRanges(string ips, List<IPAddressRange> list) 
    { 
     var splitMaskedIPs = ips.Split(','); 
     IPAddress lowerIp; 
     IPAddress upperIp; 
     foreach (string maskedIp in splitMaskedIPs) 
     { 
      var ipRange = maskedIp.Split('-'); 
      if (IPAddress.TryParse(ipRange[0], out lowerIp) && IPAddress.TryParse(ipRange[1], out upperIp)) 
       list.Add(new IPAddressRange(lowerIp, upperIp)); 
     } 
    } 

    protected void HandleUnauthorizedRequest(AuthorizationContext context) 
    { 
     context.Result = new RedirectToRouteResult(new RouteValueDictionary { { "Controller", "Home" }, 
                        { "Action", "Login" }, 
                        { "OriginalURL", context.HttpContext.Request.Url.AbsoluteUri } }); 
    } 

    protected bool AuthorizeCore(AuthorizationContext context) 
    { 
     try 
     { 
      string userIPString = context.HttpContext.Request.UserHostName; 
      IPAddress userIPAddress = IPAddress.Parse(userIPString); 

      // Check that the IP is allowed to access 
      bool? ipAllowed = CheckAllowedIPs(userIPAddress) ? true : (bool?)null; 

      // Check that the IP is not denied to access 
      ipAllowed = CheckDeniedIPs(userIPAddress) ? false : ipAllowed; 

      if (ipAllowed.HasValue) 
      { 
       return ipAllowed.Value; 
      } 

      var serverSession = context.HttpContext.Session; 

      UserSession session = null; 

      //usersession in server session 
      if (serverSession[Settings.HttpContextUserSession] != null) 
      { 
       session = (UserSession)serverSession[Settings.HttpContextUserSession]; 
       Trace.TraceInformation($"[{MethodBase.GetCurrentMethod().Name}] UserId:" + session.UserId + ". ClientId: " + session.ClientId); 
       return true; 
      } 

      //usersession in database from cookie 
      session = UserSession.GetSession(context.HttpContext.Request.Cookies.Get("sessionId").Value); 
      if (session != null) 
      { 
       Trace.TraceInformation($"[{MethodBase.GetCurrentMethod().Name}] Session found for cookie {context.HttpContext.Request.Cookies.Get("sessionId").Value}"); 
       serverSession[Settings.HttpContextUserSession] = session; 
       Trace.TraceInformation($"[{MethodBase.GetCurrentMethod().Name}] UserId:" + session.UserId + ". ClientId: " + session.ClientId); 

       return true; 
      } 
      else 
      { 
       Trace.TraceInformation($"[{MethodBase.GetCurrentMethod().Name}] No session found for cookie {serverSession["cookie"]}"); 
       return false; 
      } 

     } 
     catch (Exception ex) 
     { 
      Trace.TraceError($"[{MethodBase.GetCurrentMethod().Name}] exception: {ex.Message} - trace {ex.StackTrace}"); 
      return false; 
     } 
    } 

    public void OnAuthorization(AuthorizationContext actionContext) 
    { 
     if (IsPublic == false && AuthorizeCore(actionContext) == false) 
     { 
      HandleUnauthorizedRequest(actionContext); 
     } 
    } 
} 
0

tôi tìm thấy giải pháp sabbour của tuyệt vời nhưng cần thiết để thực hiện hai thay đổi hữu ích hơn cho mục đích của tôi:

  1. Cho phép truy cập nếu danh sách cho phép là trống rỗng. Bằng cách này, bạn có thể cho phép bất kỳ IP nào bằng cách thay đổi cấu hình (ví dụ:để triển khai thử nghiệm) hoặc cho phép tất cả các IP ngoại trừ các IP bị từ chối một cách rõ ràng. Để thực hiện điều này, tôi mở rộng IPList để bao gồm tước tài sản và kiểm tra xem nó như một phần của CheckAllowedIPs:

    return _allowedIpListToCheck.Count == 0 || _allowedIpListToCheck.CheckNumber(userIpAddress); 
    
  2. Override HandleUnauthorizedRequest luôn luôn trở lại 403. Các AuthorizeAtrribute trả 401 theo mặc định:

    public override void OnAuthorization(AuthorizationContext actionContext) 
    { 
        if (AuthorizeCore((HttpContextBase)actionContext.HttpContext)) 
         return; 
        HandleUnauthorizedRequest(actionContext); 
    } 
    
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) 
    { 
         filterContext.Result = new HttpStatusCodeResult(403, "IP Access Denied"); 
    } 
    

Dưới đây là biến thể đầy đủ của lớp FilterIpAttribute:

public class FilterIpAttribute:AuthorizeAttribute 
{ 

    #region Allowed 
    /// <summary> 
    /// Comma seperated string of allowable IPs. Example "10.2.5.41,192.168.0.22" 
    /// </summary> 
    /// <value></value> 
    public string AllowedSingleIPs { get; set; } 

    /// <summary> 
    /// Comma seperated string of allowable IPs with masks. Example "10.2.0.0;255.255.0.0,10.3.0.0;255.255.0.0" 
    /// </summary> 
    /// <value>The masked I ps.</value> 
    public string AllowedMaskedIPs { get; set; } 

    /// <summary> 
    /// Gets or sets the configuration key for allowed single IPs 
    /// </summary> 
    /// <value>The configuration key single I ps.</value> 
    public string ConfigurationKeyAllowedSingleIPs { get; set; } 

    /// <summary> 
    /// Gets or sets the configuration key allowed mmasked IPs 
    /// </summary> 
    /// <value>The configuration key masked I ps.</value> 
    public string ConfigurationKeyAllowedMaskedIPs { get; set; } 

    /// <summary> 
    /// List of allowed IPs 
    /// </summary> 
    readonly IpList _allowedIpListToCheck = new IpList(); 
    #endregion 

    #region Denied 
    /// <summary> 
    /// Comma seperated string of denied IPs. Example "10.2.5.41,192.168.0.22" 
    /// </summary> 
    /// <value></value> 
    public string DeniedSingleIPs { get; set; } 

    /// <summary> 
    /// Comma seperated string of denied IPs with masks. Example "10.2.0.0;255.255.0.0,10.3.0.0;255.255.0.0" 
    /// </summary> 
    /// <value>The masked I ps.</value> 
    public string DeniedMaskedIPs { get; set; } 


    /// <summary> 
    /// Gets or sets the configuration key for denied single IPs 
    /// </summary> 
    /// <value>The configuration key single I ps.</value> 
    public string ConfigurationKeyDeniedSingleIPs { get; set; } 

    /// <summary> 
    /// Gets or sets the configuration key for denied masked IPs 
    /// </summary> 
    /// <value>The configuration key masked I ps.</value> 
    public string ConfigurationKeyDeniedMaskedIPs { get; set; } 

    /// <summary> 
    /// List of denied IPs 
    /// </summary> 
    readonly IpList _deniedIpListToCheck = new IpList(); 
    #endregion 

    protected override bool AuthorizeCore(HttpContextBase httpContext) 
    { 
     if (httpContext == null) 
      throw new ArgumentNullException("httpContext"); 

     string userIpAddress = httpContext.Request.UserIp(); 

     try 
     { 
      // Check that the IP is allowed to access 
      bool ipAllowed = CheckAllowedIPs(userIpAddress); 

      // Check that the IP is not denied to access 
      bool ipDenied = CheckDeniedIPs(userIpAddress); 

      //Only allowed if allowed and not denied 

      bool finallyAllowed = ipAllowed && !ipDenied; 


      return finallyAllowed; 
     } 
     catch (Exception e) 
     { 
      // Log the exception, probably something wrong with the configuration 
     } 

     return true; // if there was an exception, then we return true 
    } 

    /// <summary> 
    /// Checks the allowed IPs. 
    /// </summary> 
    /// <param name="userIpAddress">The user ip address.</param> 
    /// <returns></returns> 
    private bool CheckAllowedIPs(string userIpAddress) 
    { 
     // Populate the IPList with the Single IPs 
     if (!string.IsNullOrEmpty(AllowedSingleIPs)) 
     { 
      SplitAndAddSingleIPs(AllowedSingleIPs, _allowedIpListToCheck); 
     } 

     // Populate the IPList with the Masked IPs 
     if (!string.IsNullOrEmpty(AllowedMaskedIPs)) 
     { 
      SplitAndAddMaskedIPs(AllowedMaskedIPs, _allowedIpListToCheck); 
     } 

     // Check if there are more settings from the configuration (Web.config) 
     if (!string.IsNullOrEmpty(ConfigurationKeyAllowedSingleIPs)) 
     { 
      string configurationAllowedAdminSingleIPs = ConfigurationManager.AppSettings[ConfigurationKeyAllowedSingleIPs]; 
      if (!string.IsNullOrEmpty(configurationAllowedAdminSingleIPs)) 
      { 
       SplitAndAddSingleIPs(configurationAllowedAdminSingleIPs, _allowedIpListToCheck); 
      } 
     } 

     if (!string.IsNullOrEmpty(ConfigurationKeyAllowedMaskedIPs)) 
     { 
      string configurationAllowedAdminMaskedIPs = ConfigurationManager.AppSettings[ConfigurationKeyAllowedMaskedIPs]; 
      if (!string.IsNullOrEmpty(configurationAllowedAdminMaskedIPs)) 
      { 
       SplitAndAddMaskedIPs(configurationAllowedAdminMaskedIPs, _allowedIpListToCheck); 
      } 
     } 

     return _allowedIpListToCheck.Count == 0 || _allowedIpListToCheck.CheckNumber(userIpAddress); 
    } 

    /// <summary> 
    /// Checks the denied IPs. 
    /// </summary> 
    /// <param name="userIpAddress">The user ip address.</param> 
    /// <returns></returns> 
    private bool CheckDeniedIPs(string userIpAddress) 
    { 
     // Populate the IPList with the Single IPs 
     if (!string.IsNullOrEmpty(DeniedSingleIPs)) 
     { 
      SplitAndAddSingleIPs(DeniedSingleIPs, _deniedIpListToCheck); 
     } 

     // Populate the IPList with the Masked IPs 
     if (!string.IsNullOrEmpty(DeniedMaskedIPs)) 
     { 
      SplitAndAddMaskedIPs(DeniedMaskedIPs, _deniedIpListToCheck); 
     } 

     // Check if there are more settings from the configuration (Web.config) 
     if (!string.IsNullOrEmpty(ConfigurationKeyDeniedSingleIPs)) 
     { 
      string configurationDeniedAdminSingleIPs = ConfigurationManager.AppSettings[ConfigurationKeyDeniedSingleIPs]; 
      if (!string.IsNullOrEmpty(configurationDeniedAdminSingleIPs)) 
      { 
       SplitAndAddSingleIPs(configurationDeniedAdminSingleIPs, _deniedIpListToCheck); 
      } 
     } 

     if (!string.IsNullOrEmpty(ConfigurationKeyDeniedMaskedIPs)) 
     { 
      string configurationDeniedAdminMaskedIPs = ConfigurationManager.AppSettings[ConfigurationKeyDeniedMaskedIPs]; 
      if (!string.IsNullOrEmpty(configurationDeniedAdminMaskedIPs)) 
      { 
       SplitAndAddMaskedIPs(configurationDeniedAdminMaskedIPs, _deniedIpListToCheck); 
      } 
     } 

     return _deniedIpListToCheck.CheckNumber(userIpAddress); 
    } 

    /// <summary> 
    /// Splits the incoming ip string of the format "IP,IP" example "10.2.0.0,10.3.0.0" and adds the result to the IPList 
    /// </summary> 
    /// <param name="ips">The ips.</param> 
    /// <param name="list">The list.</param> 
    private void SplitAndAddSingleIPs(string ips, IpList list) 
    { 
     var splitSingleIPs = ips.Split(','); 
     foreach (string ip in splitSingleIPs) 
      list.Add(ip); 
    } 

    /// <summary> 
    /// Splits the incoming ip string of the format "IP;MASK,IP;MASK" example "10.2.0.0;255.255.0.0,10.3.0.0;255.255.0.0" and adds the result to the IPList 
    /// </summary> 
    /// <param name="ips">The ips.</param> 
    /// <param name="list">The list.</param> 
    private void SplitAndAddMaskedIPs(string ips, IpList list) 
    { 
     var splitMaskedIPs = ips.Split(','); 
     foreach (string maskedIp in splitMaskedIPs) 
     { 
      var ipAndMask = maskedIp.Split(';'); 
      list.Add(ipAndMask[0], ipAndMask[1]); // IP;MASK 
     } 
    } 

    public override void OnAuthorization(AuthorizationContext actionContext) 
    { 
     if (AuthorizeCore((HttpContextBase)actionContext.HttpContext)) 
      return; 
     HandleUnauthorizedRequest(actionContext); 
    } 

    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) 
    { 
      filterContext.Result = new HttpStatusCodeResult(403, "IP Access Denied"); 
    } 
} 

Một phương pháp mở rộng để có được IP người dùng theo đề nghị của osa trên github

public static class HttpUtils { 

    public static string UserIp(this HttpRequestBase request) 
    { 
     var ip = request["HTTP_X_FORWARDED_FOR"]; 

     if (!string.IsNullOrWhiteSpace(ip)) 
     { 
      ip = ip.Split(',').Last().Trim(); 
     } 

     if (string.IsNullOrWhiteSpace(ip)) 
     { 
      ip = request.UserHostAddress; 
     } 

     return ip; 
    } 
} 

Và cuối cùng là sửa đổi IPList (nguồn đầy đủ là here):

internal class IpArrayList 
{ 
    //[...] 
    public int Count 
    { 
     get { return _ipNumList.Count; } 
    } 

} 

public class IpList 
{ 
     //[...] 
    public int Count 
    { 
     get { return _usedList.Count; } 
    } 
} 
Các vấn đề liên quan