我正在开发一个简单的Intranet应用程序,虽然有一些用户,但一般员工无需登录。他们应该能够从任何计算机访问Intranet,无需登录即可访问他们所需的内容。
我们的许多用户都是远程用户,他们应该能够以相同的方式进行互动。
我想要实现的目标如下:知识产权清单和直接访问根URL而不登录的子网(管理员仍然可以登录)。任何不在列入白名单的IP列表中的访问者子网应该看到静态访问被拒绝页面。在该页面上应该是登录链接。登录后,如果它们位于我们列入白名单的子网中,它们就可以与Intranet进行交互。一旦他们注销,他们就会再次看到拒绝访问的页面。
我的应用程序控制器中有以下代码:
class ApplicationController < ActionController::Base
before_filter :protect
protect_from_forgery
private
def current_user
@current_user ||= User.find(session[:user_id]) if session[:user_id]
rescue ActiveRecord::RecordNotFound
end
helper_method :current_user
def authorized?
not current_user.nil?
end
def authorize
redirect_to login_url, alert: "Not authorized" unless authorized?
end
def authorize_admin
redirect_to login_url, alert: "Not authorized" unless authorized? && current_user.admin?
end
def protect
@ips = ['127.0.0.1','123.123.123.12','192.168.5.0/24']
allowed = false
bremote_ip = 0
request.remote_ip.split('.').each { |x| bremote_ip = (bremote_ip << 8) + x.to_i }
@ips.each do |ipstring|
ip, mask = ipstring.split '/'
mask = mask ? mask.to_i : 32
bip = 0
ip.split('.').each { |x| bip = (bip << 8) + x.to_i }
bmask = ((1 << mask) - 1) << (32 - mask)
if bip & bmask == bremote_ip & bmask
allowed = true
break
end
end
if not allowed
render :template => "static/protect", :layout => "static"
return
end
end
end
任何关于如何实现这一点的指示将不胜感激。谢谢!
答案 0 :(得分:3)
来自:Rails 3 - Whitelisting list of IPs via routes
使用netaddr
gem:
before_filter :protect
def protect
@ips = []
@ips << NetAddr::CIDR.create('127.0.0.0/8')
@ips << NetAddr::CIDR.create('192.168.5.0/24')
@ips << NetAddr::CIDR.create('123.123.123.12')
valid = @ips.select {|cidr| cidr.contains?(request.remote_ip) }
if valid.empty? and !authorized?
authorize
return
end
end
修改强>
在这种情况下,上面的示例只是跳过静态保护页面并将用户重定向到登录页面。我不明白是否需要中间静态页面?
注意:为避免“重定向太多”错误,您可以在:except
语句中添加before_filter
。或者,如果您使用的是Devise,则将其添加到config/application.rb
:
# In config/application.rb
module YourAppNameHere
class Application < Rails::Application
# Whatever else is already here...
# The part to add
config.to_prepare do
Devise::SessionsController.skip_before_filter :protect
end
end
end