2012-10-21 82 views
1

我在一个简单的Intranet应用工作,虽然有一些用户,对普通员工登录没有要求。他们应该能够从任何计算机访问内网和访问他们需要的东西无需登录。Rails路由和身份验证?

我们的许多用户是远程的,他们应该能够以同样的方式进行交互。

我想实现如下; &子网直行到根网址无需登录(管理员仍然可以登录)的IP地址列表。任何访客不列入白名单的IP列表上&子网应该看到静态拒绝访问页面。在那个页面上应该是一个登录链接。登录后,他们可以与内联网只是因为他们可以,如果他们在我们的白名单中的子网进行交互。一旦他们注销,他们会再次看到拒绝访问页面。

我有下面的代码在我的应用程序控制器:

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 

就如何实现这一目标的任何指针将不胜感激。谢谢!

回答

3

来源:Rails 3 - Whitelisting list of IPs via routes

使用netaddr宝石:

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语句中。或者,如果你使用的设计,您添加到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 
+0

除非我失去了一些东西,那不是重复,我已经相同的功能?阻止任何不在白名单上的人,但不允许任何不在白名单上的人访问 - 即使他们登录了? – dannymcc

+0

@dannymcc对不起 - 我不明白你的主要问题是什么。上面更新。 – mccannf

+0

你当然是对的。静态页面令人困惑。我基本上希望不在白名单上的任何人都必须登录查看任何内容,而白名单上的用户应该看到任何不需要验证的内容。 – dannymcc