【问题标题】:Rails routes and authentication?Rails 路由和身份验证?
【发布时间】:2012-10-11 09:47:38
【问题描述】:

我正在做一个简单的Intranet应用程序,虽然有一些用户,但一般员工不需要登录。他们应该能够从任何计算机访问 Intranet 并在不登录的情况下访问他们需要的内容。

我们的一些用户是远程用户,他们应该能够以相同的方式进行交互。

我想要实现的是以下内容;无需登录即可直接进入根 URL 的 IP 和子网列表(管理员仍然可以登录)。任何不在白名单 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

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

【问题讨论】:

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


    【解决方案1】:

    发件人: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
    

    编辑

    在这种情况下,上面的示例只是跳过了静态保护页面并将用户重定向到登录页面。我不明白中间静态页面的必要性?

    注意:为避免“重定向过多”错误,您可以在 before_filter 语句中添加 :except。或者,如果您使用的是 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
    

    【讨论】:

    • 除非我遗漏了什么,否则不会重复我已经拥有的相同功能吗?阻止不在白名单上的任何人,但根本不允许不在白名单上的任何人访问 - 即使他们登录?
    • @dannymcc 抱歉 - 我不明白您的主要问题是什么。以上更新。
    • 您当然是正确的。静态页面令人困惑。我基本上希望不在白名单上的任何人都必须登录才能看到任何内容,而白名单上的人应该看到不需要身份验证的任何内容。
    猜你喜欢
    • 2016-12-11
    • 1970-01-01
    • 2013-05-16
    • 2021-12-16
    • 2017-09-24
    • 2020-02-06
    • 2020-06-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多