Top > 開発ガイド > コンポーネント開発逆引きリファレンス > 不正アクセスを防止する(モデルベース承認)

不正アクセスを防止する(モデルベース承認)

対象バージョン

当ドキュメントはRubricks-0.6.x向けです。

概要

Rubricksはグループベースのアクセス制御の仕組みを持っています。
それに加えて、モデルベース承認を宣言的に制御できるライブラリを準備しています。

モデルベース承認とは、アクセスしてきたユーザが、そのアクセスで取り扱うモデルを触る権限があるかどうかで制御を行うものです。
Railsであれば

http://xxxx.com/component/controller/show/1

と言った形でモデルのIDを指定して情報参照することが一般的です。

このような形式では、URLを推測して本来見ることができないモデルのIDを直接URL欄から入力するような不正アクセスを防ぐ仕組みが必要です。
本ライブラリはその処理を宣言的に実現する機構を提供します。

例えば、下記のようなアプリケーションを作成したい場合に利用できます。

  • 自分のTodoは他のユーザには見られてはならない
  • 部下の報告書は上司及び同僚のみが閲覧できる
  • 勤務報告書は上司または勤務報告コンポーネント管理者のみが閲覧できる

注意 本ライブラリは、直接アクセスによる不正なアクセスに対応するためのものであることに注意して下さい。 正常なユーザが正常にアクセスしてきた場合の挙動は従来どおり実装する必要があります。

使い方

規約(Convention over Configuration)

本ライブラリは下記の規約に則ることで記述量を削減できます。 これらの規約に則らない場合は、オプションで明示的な指定が必要になります。

  • モデルのownerを示す外部キーカラム名を「created_by」にする
  • 指定モデルIDのリクエストパラメータ名を「id」にする

サンプル

  1. 規約に則ってモデルは下記のような構成とします。created_byはREPORTSを作成したユーザのIDです。
  • REPORTSテーブル
idtitlecontentscreated_by
1報告書1報告します・・・3
2報告書2報告ですが・・・4
  1. コントローラでauthorize_by_modelメソッドを宣言的に記述します。
    class XxxController < ApplicationController
    	authorize_by_model Report, :auth_action => {:only => :show}, :auth_type => :owner
    	def main
    	  #...
    	end
    	
    	def update
    	  #...
    	end
    	
    	def show
    	  #...
    	end
    end
    
  1. ビューではリクエストパラメータに「キー名:id、値:モデルのID」を指定します。
    <%= link_to 'click', :controller => 'xxx', :action => 'show', :id => 1 %>
    

結果

ユーザIDが3のユーザ(ID=1のREPORTSのowner)でログインしていれば、showアクションを実行することができる。 そうでなければ、不正アクセスとしてはじかれる。

処理の流れ

  1. IDが3のユーザでログインしてビューのclickリンクを押すと、
  2. XxxController?のshowメソッド宛てにパラメータ「id : 1」でリクエストが飛ぶ
  3. showアクションが実行される前にフィルタでチェックが走る
    • Report.find(@params[:id])を実行し、REPORTSテーブルからモデルを取得する
    • 取得したモデルのcreated_byで紐づくユーザを取得する
    • シンボル:ownerからOwnerAuth?クラスが認識される。
    • OwnerAuth?クラスで取得したユーザとログインユーザが等しいか判断
      • 等しければshowアクションを実施する
  4. show以外のアクションにはフィルタが張られていないので通常通りのアクセスとなる

使用例集

  • アクセス制御するアクションを指定する
    authorize_by_model Report, :auth_action => {:only => :show}
    
    authorize_by_model Report, :auth_action => {:except => :show}
    
  • 自分のモデルは自分しかアクセスできないようにする
    authorize_by_model Report, :auth_type => :owner
    
  • 状況によってauth_typeを切り替える
    authorize_by_model Report, {
    	:auth_type => lambda{|owner_user, current_user, model, param|
    		Date.today.year < 2006 ? :owner, :any
    	}
    }
    
  • 自分自身かsystemコンポーネントのaccess権限があればアクセスできるようにする
    authorize_by_model Report,{
    	:auth_type => [:owner, {:component => :system, :function => :access}]
    }
    
  • 自分自身で、かつsystemコンポーネントのaccess権限があればアクセスできるようにする
    authorize_by_model Report, :auth_type => :owner
    authorize_by_model Report, :auth_type => {:component => :system, :function => :access}
    
  • 「created_by」以外の外部キー名でownerを参照する
    authorize_by_model Report, :owner => :owner_id
    
  • 交差テーブルで紐づくownerを参照する
    authorize_by_model Report, {
    	:owner => lambda{|model, current_user, params|
    		model.xxx.rubricks_user
    	}
    }
    
  • 独自の判定基準でアクセス制御をする
    • 独自のauth_typeを追加できる
    • :auth_typeにシンボルを指定すると、「シンボル+'Auth'のキャメルケース」クラスのauthorizeメソッドを呼ぶ
      class OriginalAuth
      	def self.authorize(owner_user, current_user, model, params)
      		Date.today.year < 2006
      	end
      end
      
      authorize_by_model Report, :auth_type => :original
      
    • クラス名にモジュール名がついている場合、シンボルでは「::」の代わりに「/」で記述する
      class Sample::GoodAuth
      	def self.authorize(owner_user, current_user, model, params)
      		true
      	end
      end
      
      authorize_by_model Report, :auth_type => :'sample/good'
      
  • @params[:id]以外のパラメータでモデルのIDを扱う
    authorize_by_model Report, :model_id_in_param => :model_id
    
  • params[:id]にユーザID自体が渡ってくる場合を扱う
    authorize_by_model RubricksUser, {
      :owner => :id,
      :auth_type => [:owner, {:component => :abc, :function => :admin}],
      :auth_action => {:only => [:show_user, :update]}
    }
    

関連項目

API

authorize_by_model(model_class, options)

  • コントローラを拡張して権限チェックを追加するメソッドです。
引数必須初期値説明
model_class-ActiveRecord::Base承認の条件となるモデル。!ActiveRecord::Baseを継承している前提。
options-Hash詳細は下記「オプション」参照。

オプション

キー 必須 初期値 説明
:model_id_in_param - :id Symbol/String モデルのIDが格納されているとみなされる@paramsのキー値を指定する。
:owner - :created_by Symbol/String
Proc
モデルownerを示す、モデルテーブルの外部キー名を指定する。
モデルownerのインスタンスを返却させるようにする。
:auth_type - :owner Symbol/String
Hash
Proc
Array
承認方法を示すシンボル名。デフォルトでは:any(誰でもOK), :nobody(誰でもNG), :owner(自分自身だけがアクセス可)が指定できる。
:component, :functionを渡した場合、該当コンポーネントのfunctionの権限を持っていればアクセスできる。
true/falseを返却することで承認するかを決められる。シンボルを返却すると、上記シンボルを指定した場合と同様の承認がなされる。
上記Symbol,Hash,Procを入れ込むことができ、or条件で判定する。
:auth_action - {} Hash アクセス制御対象のアクションを指定する。フォーマットはfilterのオプションに順ずる(:only,:exceptなど)
:category - nil Symbol/String モデルクラスのカテゴリをしめすカラム名を指定する。カテゴリが異なるモデルを取り扱おうとすると不正アクセスとしてはじかれる。指定しなければ無視される。
:params - {} Hash 各Procにパラメータとして引き渡される値。@paramsの値とマージされる。