Rails路由和身份验证?

时间:2012-10-21 10:17:23

标签: ruby-on-rails-3 authentication controller routes

我正在开发一个简单的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

任何关于如何实现这一点的指示将不胜感激。谢谢!

1 个答案:

答案 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