凪瀬 Blog
Programming SHOT BAR

目次

Blog 利用状況
  • 投稿数 - 260
  • 記事 - 0
  • コメント - 46859
  • トラックバック - 192
ニュース
広告
  • Java開発者募集中
  • 経歴不問
  • 腕に自信のある方
  • 富山市内
  • (株)凪瀬アーキテクツ
アクセサリ
  • あわせて読みたい
凪瀬悠輝(なぎせ ゆうき)
  • Java技術者
  • お茶好き。カクテル好き。
  • 所属は(株)凪瀬アーキテクツ
  • Twitter:@nagise

書庫

日記カテゴリ

 

ちゃっぴさんのblogに変な返答をしてしまったので、言い出しっぺの法則に基づき、方法論を考えてみました。

テーマはあるWebアプリケーション(以下、システムと言う場合はアプリケーション全体を指す)があったとして、 そのシステム全体でデータに対するアクセス権を管理するためにはどうしたらよいだろうか?です。 *1

ここではOOP(オブジェクト指向)でいうObject単位での権限管理を考えます。 これらのObjectはRDBMSなどで管理されるような永続性のあるデータを想定しています。

ユーザの保有する権限の管理

例えば、システム内でプロジェクトを表現するクラスProjectがあったとして、 参照、新規、更新、削除の4つの権限を持つとしましょう。 さらに、Projectのインスタンス単体でこれらの権限が設定できるとしたならば、 ユーザ側の情報に、どのProjectに対して何権限を持つのかの情報を持たなくてはなりません。

まず、権限の種別を表す列挙を用意します。

public enum AuthorityType {
  /** 参照権 */
  SELECT,
  /** 登録権 */
  INSERT,
  /** 更新権 */
  UPDATE,
  /** 削除権 */
  DELETE,
}

そして、権限管理クラスでは対象となるオブジェクトのID・型とその権限を保持するようにします。 今回は簡単のためIDによって対象データを特定する方式をとっています。 *2

一般的なWebシステムを想定するとすれば、このユーザの権限情報はセッションに保持されます。 このオブジェクトをProjectオブジェクトを操作するたびに権限確認のために引き渡すのはデータの取り回しがあまりに大変なので HTTPの1リクエストごとに、1つのThreadが立てられることを利用してjava.lang.ThreadLocalに この権限情報を格納して利用するとしましょう *3。 ThreadLocalはそのThread内だけをスコープとするグローバル変数のようなものとイメージしてもらうと大体当たっていると思います。

/**
 * ユーザが保持する権限を管理するクラス
 * ユーザ単位で1インスタンスが作られる。
 */
public class AuthorityManager {
  /** ThreadLocalでThread内をスコープとするグローバル変数を作る */
  private static ThreadLocal<AuthorityManager> manager = new ThreadLocal<AuthorityManager>();
  private static final String SESSION_KEY = "AuthorityManager";
  /** セッションから権限情報を取得してThreadLocalに設定する */
  public static void initManager(HttpServletRequest request) {
    HttpSession session = request.getSession();
    AuthorityManager auth = (AuthorityManagersession.getAttribute(SESSION_KEY);
    manager.set(auth);
  }
  /** ThreadLocalから権限情報を解放する */
  public static void releseManager() {
    manager.remove();
  }

  /** 保有権限のList */
  private List<Tips> authList;

  static class Tips {
    /** 対象オブジェクトのID */
    int id;
    /** 対象オブジェクトの型 */
    Class objectType;
    /** 権限タイプ */
    AuthorityType type;
  }
}

/**
 * HTTPのリクエスト毎に権限情報を設定するFilter
 */
public class AuthorityInitFilter implements Filter {
  @Override
  public void init(FilterConfig configthrows ServletException {}
  @Override
  public void destroy() {}
  @Override
  public void doFilter(ServletRequest request, ServletResponse response,
      FilterChain chainthrows IOException, ServletException {
    // 権限情報をThreadLocalに設定
    HttpServletRequest httpRequest = (HttpServletRequest)request;
    AuthorityManager.initManager(httpRequest);
    try {
      // 実際のServletの処理
      chain.doFilter(request, response);
    finally {
      // 権限情報をThreadLocalから解放する
      AuthorityManager.releseManager();
    }
  }
}

実装は省いていますが、保有データからユーザ側に保有権限のListを持たせ、権限認証の際に割符のように 操作対象となるオブジェクトと付き合わせようという思惑なのをイメージして頂けますでしょうか。

権限チェックを漏れがないように執り行う

さて、Thradにアクセス権限の情報を持ちました。 あとは対象となるProjectオブジェクトから権限のある場合のみデータが参照できるように網羅しなくてはなりません。 これは、Projectオブジェクトへのアクセス全てに対して 「権限チェックをし権限のないアクセスであれば例外を投げるという処理」 を差し挟むということですから、AOP(アスペクト指向)で言う「横断的関心事」となります。

さて、この横断的関心事ですが、AOP対応の言語であれば、言語機能を用いてウィービング (アスペクトはWeaving、縫い付けると表現します)すればよいのでしょうが ご承知のとおりJavaはそうではないので、なんらかの手段を講じなければなりません。

ProjectオブジェクトがDIコンテナによって管理されている場合、DIコンテナのAOP機能でウィービングする手が使えるでしょう。 DIコンテナは現行の非AOPな言語でAOPを実践するための工夫と捉えることもできます。 *4

DIコンテナを用いていなくとも、Projectオブジェクトの取得する口が特定できるならそこを抑えてProxyを噛ませる手が使えます。 GoFデザインパターンのProxyパターンはOOPの範囲で出来るAOPへの対処法とも言えます *5 *6

場合によってはダサいですがProxyクラスさえも用意せず、Projectオブジェクトの各メソッドに 権限チェック処理を直接実装する手法を用います。 横断的関心事を分離できていないわけですが、setter、getterなんぞそもそも処理が希薄なので割りきることもできることでしょう。

注意点として、Proxyパターンや、直接Projectオブジェクトに権限チェックを実装するような場合、メソッドの網羅は保証できません。 なんせ、手で個別のメソッドに対応を差し挟むわけですから。 機械的な網羅ではないのでヒューマンエラーで容易に漏れてしまいますし、なにより記述が面倒です…。 もちろん、Projectクラス自体をアーキテクト管理下に置いて、勝手に改変されないような状況である必要があります。 *7

ここまですると、開発時に参照件のないProjectオブジェクトを取得して、その情報を参照しようとした時点で 実行時例外を起こすことができるようになるわけです。 もちろん、処理効率的にはよくないわけですが、セキュリティ的にはいくらかの安全性を担保できることでしょう。

まとめ

設計パラダイムとしては、まず該当オブジェクトへの操作に対する権限チェックをアスペクトとして捉える事。 また、これをうまくウィービングして全ての参照/設定メソッドに網羅させること。

そして、処理の実行体であるThreadと、操作対象であるオブジェクト (上記例ではProjectオブジェクト)との間の権限確認を行います *8

Threadを用いないでオブジェクトを操作することはできないですし、アスペクト指向によってオブジェクトに対するアクセス全てに 権限確認処理をウィービングすることで、ヒューマンエラーによる誤操作をすべてはじき出すわけです。

また、悪意ある故意の操作に対しても処理をはじくことがある程度できます。 もっともThreadの持つ権限管理データまで改ざんされるとアウトなわけですが…。

なお、ここで挙げた設計方法は、1案に過ぎません。よりよい方法論もあることでしょう。 この方法論を試すのは自由にしていただいて構いませんが、 私はこの設計方法を採用して発生したいかなる損失に対してもなんらの責任は負わないものとします。

注釈

*1元のコメントではシステムの範囲を誤解させてしまいました… orz

*2 RDBMSでのプライマリキーとなることも考慮してIDによって対象となるObjectを対応付けていますが、 本当はProjectオブジェクトへの参照によって対応付けを行いたいところです。 Projectオブジェクトの数が限られ、システム全体で完全にキャッシュされるようなケースであれば容易でしょう。
全てキャッシュできるほどにProjectオブジェクトが少ないわけではないとすれば、 Projectオブジェクトの参照は同一に遅延ロードを実装する手法も考えられます。
なお、アクセス速度を考えるとListよりはMapなどの構造を取った方が適切でしょう。 このあたりは実際のデータを鑑みて考慮する必要があります。

*3 ただし、通常ServletではThreadがプールされるため、HTTPのリクエストの処理開始で格納し、 処理終了時には削除するようにしておかなければいけません。 これはjavax.servlet.Filterで処理することで漏れなく確実な処理を行うことができます。

*4 アスペクトがDIのすべてとは言いませんが、AOP対応言語ではDIコンテナを使う意味があまりないはずです。 DIはコンストラクタに対するアスペクトとして実装することができてしまう。 強いて言えば、設定ファイルを読み込んでリフレクションで設定を行うところが面倒なので、 そのあたりをやってくれる程度には便利と思いますが。

*5 例えば、Projectオブジェクトを取得するためのサービスが限定されているようなケースでは、 その出口を抑えて、GoFデザインパターンのProxyパターンを適用すればよいのです。 Proxyクラスの実装はProjectオブジェクトを継承し、全機能をProjectに委譲するようにしておきます。 ただし、getterメソッド全てに参照件のチェックを差し挟むし、setter全てに更新件のチェックを差し挟むわけです。

*6 ProxyパターンでAOPをする場合の最大の障壁は、オブジェクトの生成箇所をどのようにして抑えるかという点。 new演算子で生成されると手の打ちようがありません。 生成に関するデザインパターンなどを用いて、オブジェクトの生成部を一元管理できているようなケースではどうにかなります。 DIコンテナも生成をDIコンテナが一身に背負うことでProxyパターンによるAOPを成し遂げているわけです。

*7 変更する人が状況をよく理解している少数であったとしても、修正に際してAOPの対応漏れは容易に発生します。 誰もが変更できる状況下では維持するためのコストは膨大になることでしょう。

*8 1Threadあたり1Userという状況下である必要があります。 世の中にはあるいは1Threadあたり複数userとなるシステムもあるかもしれませんが、 そういうケースではこの手法ではうまくいかないことになってしまいます。

投稿日時 : 2008年5月13日 0:22
コメント
  • # re: OOPでシステム内のオブジェクトのアクセス権を管理する
    ちゃっぴ
    Posted @ 2008/05/13 1:35
    なるほど、そういうことでしたか。ここら辺の設計ということなら OS の access control がどのように行われているか?研究するのが一番でしょうね。まず proxy pattern だと思いますが。

    でも、すでにちゃんとしたものが用意されているので、あえて自作することは無いんじゃないかと思います。

    ってか、やっぱり spam keyword に引っかかるのよね。
  • # re: OOPでシステム内のオブジェクトのアクセス権を管理する
    凪瀬
    Posted @ 2008/05/13 8:41
    「すでにちゃんとしたものが用意されているので」って言うのは何を指しています?
    既存のものがあるなら利用したいところですが…

    > ってか、やっぱり spam keyword に引っかかるのよね。
    wankuma.comでのスパム対策が不透明すぎますね^^;
    一律適用はちょっと問題あるだろうとは思うんですが…
    blogシステムが刷新されでもしないと直らないだろうなぁ…
  • # re: OOPでシステム内のオブジェクトのアクセス権を管理する
    れい
    Posted @ 2008/05/13 11:02
    OSの機能とかDBの機能を使わずにアクセス制御を作ってみよう!
    っていう話ですよね?

    私もよくこんな感じに作りますが、
    権限情報の保存の問題とか、
    制御単位はスレッドごとでいいのかとか、
    オブジェクトごとのアクセス権の違いだとか、
    アクセス権の種類だとか、
    実際にはいろいろ考えなきゃいけないことが多くて大変です。

    設計段階では単純できれいなんですが、
    実装段階ではぐちゃぐちゃになって、
    運用段階では結局全員adminになってしまう、
    みたいな事がよくあります。

    OSやDBの仕組みは大きいので使うのが大変。
    かといって自分で作るのはちょっと骨が折れる。

    アクセス制御ではそんなことが多いです。
  • # re: OOPでシステム内のオブジェクトのアクセス権を管理する
    凪瀬
    Posted @ 2008/05/13 11:55
    > OSの機能とかDBの機能を使わずにアクセス制御を作ってみよう!

    ちょっと違って、まず、情報の1次ソースというか、格納庫は通常DBなわけですが、
    ちゃっぴさんの話題では、このDBから情報取得する際のUserが、アプリケーションで単一になっていることが多くてマズイよね、という話でした。

    じゃぁ、参照のみのUserと更新もできるUserを作れば事足りるかと言うと、それはDBとアプリケーションの間の情報の流通を制御するだけのことで
    アプリケーションに渡された後の情報の流通網は規制なしの野放しなわけです。

    そこで、アプリケーション内部でも情報流通をトラッキングするか、ないし引き渡し部分に網を張って不正な流通をしないように監視する機構が必要だよねという話になる。
    そして、その部分と言うのがOSの機構とかDBの機構ではできないんじゃないの?ということで、自作するならこういう設計になるよねというところが本稿。
    このアプリケーション上での情報流通を制御できる既存の機構があるならば、やはりあるものを使いたいわけで、作りたいわけではないのですよ。
  • # re: OOPでシステム内のオブジェクトのアクセス権を管理する
    れい
    Posted @ 2008/05/14 14:08
    > そこで、アプリケーション内部でも情報流通をトラッキングするか、ないし引き渡し部分に網を張って不正な流通をしないように監視する機構が必要だよねという話になる。

    うーん。そういうことだったのか。
    ぜんぜん読めませんでした。

    それが書かれてるのはこの辺かしら。
    > Object単位での権限管理を考えます
    Injectionつながりだったわけですね。

    ユーザーが知りうるかというメタ情報をオブジェクトに持たせて管理するための機構が欲しい、
    ということでいいのかしら。


  • # re: OOPでシステム内のオブジェクトのアクセス権を管理する
    凪瀬
    Posted @ 2008/05/14 17:34
    > ユーザーが知りうるかというメタ情報をオブジェクトに持たせて管理するための機構が欲しい、
    > ということでいいのかしら。

    本稿ではユーザをThreadとして扱っているけども、それでいいのかという根本的な議論もありますね。

    一般に、プログラムというのはデータの流れを追うのは難しくて、予期しない不正なデータが紛れ込んできたというバグへの対処が難しいわけです。
    どこでそんなデータを放流したんだという特定が難しい。

    Objectよ、汝の出自を示せ
    http://blogs.wankuma.com/nagise/archive/2007/08/20/91054.aspx
    では、スタックトレースの仕組みを使ってデータの出所を突き止めるという工夫について触れているのだけども、
    今回の話題と言うのは、見えてはいけないデータが見られそうになった時点でそれを検出しようという方向性ですね。
    このあたりも、工夫で対処するというのは相応に手間ですから、言語機構としてデータの流れが管理できるとよいのに、と思う次第です。

    アサーションとかは方向性は違うけど、不正データの早期検出という目的でも使えることは使えますね。
    アサーションをアスペクト指向でウィービングできるとあるいは相応の解決になるのかな?本稿とやっていることはあまり変わらないかw
  • # JQMivZarRTkeXtomh
    http://www.discreetpharmacist.com/
    Posted @ 2011/12/22 20:47
    c7l1OY Very amusing thoughts, well told, everything is in its place:D
  • # xgoKOJTHVwlPaAfoW
    http://crorkz.com/
    Posted @ 2014/08/28 15:25
    P98apR fantastic points altogether, you just gained a new reader. What would you suggest about your post that you made a few days ago? Any positive?
  • # dYDaYuwhJpMFjV
    http://nubiadesign.com/blog/
    Posted @ 2014/08/29 12:52
    Wonderful site. A lot of useful info here. I am sending it to some pals ans additionally sharing in delicious. And of course, thanks on your sweat!
  • # BMVuWSMcBMJDcJuP
    http://vender-por-internet.net/
    Posted @ 2014/09/09 10:06
    I've read several good stuff here. Definitely value bookmarking for revisiting. I surprise how a lot attempt you place to make such a fantastic informative web site.
  • # ZYvhpzcHVOSbIQEUq
    https://www.youtube.com/watch?v=6l8bpZ0oY_M
    Posted @ 2014/09/10 18:09
    This web site can be a stroll-through for all of the info you needed about this and didn't know who to ask. Glimpse here, and you'll definitely uncover it.
  • # QMvQejiLlyHUpviYp
    http://www.youtube.com/watch?v=6eoaR-4GvzQ
    Posted @ 2014/09/12 20:33
    I am always looking online for tips that can help me. Thx!
  • # SscxmBfqjLSTyGOmex
    https://local.amazon.com/north-orange-county/B00NF
    Posted @ 2014/09/17 18:51
    Wonderful site. Lots of useful information here. I am sending it to some friends ans also sharing in delicious. And certainly, thanks for your effort!
  • # tnZJeKGnixSQwzkF
    http://ywgs2011.info/story.php?id=35077
    Posted @ 2014/09/18 17:13
    9cKO6Z I am so grateful for your article post. Awesome.
  • # bracciale love cartier replica
    nedjrpgpv@aol.com
    Posted @ 2015/08/03 2:09
    Hi Mindy I haven’t heard that before and I’m not sure why someone would tell you that… Was it an oncologist?
    bracciale love cartier replica http://www.bestcartierlovebracelet.com/it/
  • # sac chanel matelassé noir prix
    hmnysmheyl@aol.com
    Posted @ 2015/08/04 2:11
    How do I add the “Proceed to checkout” button on the shopping cart page of the mobile template? It seems to be missing.
    sac chanel matelassé noir prix http://www.replicasbag.net/fr/classic-chanel-255-flap-bag-a37587-black-quilted-aged-calfskin-ruthenium-metal-p289/
  • # クリスチャンルブタン 財布 コピー
    kicyfiqlp@hotmail.co.jp
    Posted @ 2017/09/23 3:18
    とても丁寧な対応をして頂きました。
    こちらのムリも聞いて頂いて
    気持ち良い取引ができましました。
    ありがとうございました。
    クリスチャンルブタン 財布 コピー http://www.baggobuy.com
  • # 偽物ルイヴィトンバッグ
    xqcdrul@live.jp
    Posted @ 2017/12/01 22:07
    調査によると、「環球新鋭ランキング」は中央テレビのチャンネル毎年の年末に開催のランキング類番組、全世界の範囲の内で見つめ科学技術革新、発明創造は、専門家委員会の推薦を形成し、年度ランキング。
    2012年にランクインのGDC 10新鋭科技それぞれ:マイクロソフト同時通訳ソフト、IBMの速度100倍のチップ、ミリ秒失ってない北斗衛星時報時計、可視光通信、BMWの未来超パトカーやモバイルペイメント拉?拉、シェル巨大な天然ガス収集船、太陽電池パネル、ベルがフレキシブル実験室の通信のルービック・キューブ大衆娯楽応用、怒りの小鳥。
  • # A品ルイヴィトン
    kogrnegjl@docomo.ne.jp
    Posted @ 2018/01/28 1:29
    オメガ コピー - オメガ コピー
    ★2018最高等級新しい商品大量入荷!
    ■在庫情報随時更新!(*^-^*)
    ■信用第一、良い品質、低価格は。
    ★★超人気質屋★★
    販売ルイヴィトン、グッチ、シャネル、エルメス、コーチ、
    ボッテガ・ヴェネタ、バリー、バーバリーなどのブランドバッグ、財布、アクセサリ、
    時計、靴、などでございます。
    製品はブランド品を中心としてやっており、
    主なお輸出先は欧米、日本、韓国などでございます。
    弊社は「信用第一」をモットーにお客様にご満足頂けるよう、
    発送前には厳しい検査を通じて製品の品質を保証してあげますとともに、
    配送の費用も無料とし、品質による返送、交換、さらに返金までも実際にさせていただきます。
    また、従業員一同、親切、丁寧、迅速に対応させて頂き、
    ご安心になってお買い物を楽しんでくださるよう精一杯力を尽くしていくつもりです。
    弊社の製品とほかに関して詳しくは、ホームページを一度ご覧になって
  • # Wow, this post is good, my sister is analyzing these things, therefore I am going to convey her.
    Wow, this post is good, my sister is analyzing the
    Posted @ 2018/09/18 13:09
    Wow, this post is good, my sister is analyzing these things, therefore I am going to convey her.
  • # certainly like your web site however you have to take a look at the spelling on several of your posts. Several of them are rife with spelling issues and I in finding it very troublesome to inform the truth nevertheless I'll definitely come back again.
    certainly like your web site however you have to t
    Posted @ 2018/10/25 8:27
    certainly like your web site however you have to take a look at the spelling
    on several of your posts. Several of them are rife with
    spelling issues and I in finding it very troublesome to inform the truth nevertheless I'll definitely come back again.
  • # As the admin of this site is working, no hesitation very soon it will be well-known, due to its feature contents.
    As the admin of this site is working, no hesitatio
    Posted @ 2018/10/26 1:26
    As the admin of this site is working, no hesitation very
    soon it will be well-known, due to its feature contents.
  • # I always emailed this web site post page to all my contacts, since if like to read it after that my links will too.
    I always emailed this web site post page to all my
    Posted @ 2018/10/28 0:59
    I always emailed this web site post page to all my contacts,
    since if like to read it after that my links will too.
  • # Why users still make use of to read news papers when in this technological world the whole thing is accessible on net?
    Why users still make use of to read news papers w
    Posted @ 2018/11/12 6:19
    Why users still make use of to read news papers when in this
    technological world the whole thing is accessible on net?
  • # What's up, I desire to subscribe for this web site to take most recent updates, thus where can i do it please help.
    What's up, I desire to subscribe for this web site
    Posted @ 2018/11/14 21:18
    What's up, I desire to subscribe for this web site to take most recent updates, thus where
    can i do it please help.
  • # ロレックス 時計 寿命
    svjwki@ybb.ne.jp
    Posted @ 2022/09/28 3:14
    ルイヴィトン キーホルダー タイガ ネオLVクラブ M00033 アルドワーズ 新品 ダークグレー カギ キーリング メンズ ルイ・ヴィトン
    ヴィトンでも変わったデザインで気に入っています。 品質も良品で、喜んでいます。 イニシャルも一緒なので、縁を感じて購入しました。
    質問等の対応も非常によく、安心して購入できました。
    梱包も丁寧で、お店の品位が伺えて、非常に満足しております。
    ロレックス 時計 寿命 https://www.b2kopi.com/article/list.aspx.htm
タイトル
名前
Url
コメント