舞台裏

Qiita が表でこっちが裏。こっそりやっていく。

ドメインオブジェクトセキュリティの勉強再開

        ObjectIdentityImpl oi = new ObjectIdentityImpl(Foo.class, 44L);
        MutableAcl acl = this.aclService.createAcl(oi);

とか

        ObjectIdentityImpl oi = new ObjectIdentityImpl(Foo.class, 44L);
        MutableAcl acl = this.aclService.createAcl(oi);
        System.out.println(acl.getClass());
        acl.insertAce(acl.getEntries().size(), BasePermission.READ, new GrantedAuthoritySid("role_hoge"), true);
        this.aclService.updateAcl(acl);

とかを順番に動かして、どのテーブルにどういうデータが登録されるのかを検証。

なんとなくテーブル同士のデータの関係が分かった気がする。

あと式で指定する hasPermission() の動作とかを実装を追って確認したり。

2.3. Domain Classes

Spring Security ACL Plugin - Reference Documentation

The plugin uses domain classes to manage database state.

プラグインドメインクラスをデータベースの状態を管理するために使用します。

Ordinarily the database structure isn’t all that important, but to be compatible with the traditional JDBC-based Spring Security code, the domain classes are configured to generate the table and column names that are used there.

通常、データベースの構造は重要ではありません。しかし、伝統的な JDBC ベースの Spring Security コードと互換性を持たせるため、ドメインクラスは Spring Security のコードから利用できるようにテーブル名とカラム名を生成するよう設定されます。

The plugin classes related to persistence use these classes, so they’re included in the plugin but can be overridden by running the s2-create-acl-domains script.

永続化に関係するプラグインクラスは、これらのクラスを使用します。そのため、彼らはプラグインに含まれています。しかし、 s2-create-acl-domains スクリプトの実行により上書きすることが可能です。

As you can see, the database structure is highly normalized.

ご覧の通り、データベースの構造は高度に正規化されています。

2.1. Securing Service Methods

Spring Security ACL Plugin - Reference Documentation

There are two primary use cases for ACL security: determining whether a user is allowed to perform an action on an instance before the action is invoked, and restricting access to single or multiple instances after methods are invoked (this is typically implemented by collection filtering).

ACL セキュリティについて2つの主要なユースケースがあります。
アクションが実行される前に、あるインスタンスでのアクションを実行することをユーザに許可するかどうかを決定する、そしてメソッドが実行された後で1つかもしくは複数のインスタンスへのアクセスを制限する(よくコレクションのフィルターで実装される)

You can call aclUtilService.hasPermission() explicitly, but this tends to clutter your code with security logic that often has little to do with business logic.

aclUtilService.hasPermission() を明示的に呼ぶことができます。しかし、ビジネスロジックと関係のないセキュリティロジックを一緒にするとコードは複雑になる傾向があります。

Instead, Spring Security provides some convenient annotations that are used to wrap your method calls in access checks.

代わりに、 Spring Security はいくつかの便利なアノテーションを提供しています。
それらのアノテーションはアクセスチェックの中でメソッドの呼び出しをラップするのに使われます。

There are four annotations:

4つのアノテーションがあります。

  • @PreAuthorize
  • @PreFilter
  • @PostAuthorize
  • @PostFilter

The annotations use security-specific Spring expression language (SpEL) expressions - see the documentation for the available standard and method expressions.

アノテーションはセキュリティ固有の Spring 式言語(SpEL) の式を使用します。
有効な標準やメソッド式についてドキュメントを見てください。

Here’s an example service that manages a Report domain class and uses these annotations and expressions:

ここに、 Report ドメインクラスを管理し、アノテーションと式を使用するサービスの例を示します。

import org.springframework.security.access.prepost.PostFilter
import org.springframework.security.access.prepost.PreAuthorize
import grails.transaction.Transactional

import com.yourapp.Report

class ReportService {

   @PreAuthorize("hasPermission(#id, 'com.yourapp.Report', read) or " +
                 "hasPermission(#id, 'com.yourapp.Report', admin)")
   Report getReport(long id) {
      Report.get(id)
   }

   @Transactional
   @PreAuthorize("hasRole('ROLE_USER')")
   Report createReport(params) {
      Report report = new Report(params)
      report.save()
      report
   }

   @PreAuthorize("hasRole('ROLE_USER')")
   @PostFilter("hasPermission(filterObject, read) or " +
               "hasPermission(filterObject, admin)")
   List getAllReports(params = [:]) {
      Report.list(params)
   }

   @Secured(['ROLE_USER', 'ROLE_ADMIN'])
   String getReportName(long id) {
      Report.get(id).name
   }

   @Transactional
   @PreAuthorize("hasPermission(#report, write) or " +
                 "hasPermission(#report, admin)")
   Report updateReport(Report report, params) {
      report.properties = params
      report.save()
      report
   }

   @Transactional
   @PreAuthorize("hasPermission(#report, delete) or " +
                 "hasPermission(#report, admin)")
   void deleteReport(Report report) {
      report.delete()
   }
}

The configuration specifies these rules:

設定はこれらのルールを指定しています。

  • getReport requires that the authenticated user have BasePermission.READ or BasePermission.ADMIN for the instance
  • createReport requires ROLE_USER
  • getAllReports requires ROLE_USER and will have elements removed from the returned List that the user doesn’t have an ACL grant for; the user must have BasePermission.READ or BasePermission.ADMIN for each element in the list; elements that don’t have access granted will be removed
  • getReportName requires that the authenticated user have either ROLE_USER or ROLE_ADMIN (but no ACL rules)
  • updateReport has no role restrictions but must satisfy the requirements of the aclReportWriteVoter voter (which has the ACL_REPORT_WRITE config attribute), i.e. BasePermission.ADMINISTRATION or BasePermission.WRITE
  • deleteReport has no role restrictions but must satisfy the requirements of the aclReportDeleteVoter voter (which has the ACL_REPORT_DELETE config attribute), i.e. BasePermission.ADMINISTRATION or BasePermission.DELETE

  • getReport は認証されたユーザがインスタンスに対する BasePermission.READBasePermission.ADMIN を持つことを要求します。

  • createReportROLE_USER を要求します
  • getAllReportsROLE_USER を要求し、 return されたリストのうち、ユーザに ACL が与えられていない要素が削除されます。
    ユーザは BasePermission.READBasePermission.ADMIN をリストの各要素に対して持たなければなりません。
    アクセスが許可されていない要素は削除されます。
  • getReportName は認証されたユーザが ROLE_USERROLE_ADMIN を持つことを要求します(ACL ルールではありません)
  • updateReport はロールによる制限を持ちません。しかし、 aclReportWriteVoter Voter による要求を満たす必要があります。
    (voter は ACL_REPORT_WRITE 設定属性を持ちます)
    つまり BasePermission.ADMINISTRATION または BasePermission.WRITE です。
  • deleteReport はロールによる制約がありません。しかし、 aclReportDeleteVoter Voter による要求を満たす必要があります。
    (voter は ACL_REPORT_DELETE 設定属性を持ちます)
    つまり、 BasePermission.ADMINISTRATION または BasePermission.DELETE です。

1. Introduction to the Spring Security ACL Plugin

Spring Security ACL Plugin - Reference Documentation

1. Introduction to the Spring Security ACL Plugin

The ACL plugin adds Domain Object Security support to a Grails application that uses Spring Security.

ACL プラグインは、 Spring Security を使うドメインオブジェクトセキュリティのサポートを Grails アプリケーションに追加します。

It depends on the Spring Security Core plugin.

このプラグインは Spring Security のコアプラグインに依存します。

The core plugin and other extension plugins support restricting access to URLs via rules that include checking a user’s authentication status, roles, etc.

コアプラグインと他の拡張プラグインはユーザの認証ステータス、ロール、その他をチェックするルールを通じて、 URL へのアクセス制限をサポートします。

and the ACL plugin extends this by adding support for restricting access to individual domain class instances.

そして、 ACL プラグインはこれ(URL へのアクセス制限)を拡張し、個々のドメインクラスのインスタンスへのアクセスを制限するサポートを追加します。

The access can be very fine-grained and can define which actions can be taken on an object - these typically include Read, Create, Write, Delete, and Administer but you’re free to define whatever actions you like.

アクセスはとてもきめ細かく定義でき、オブジェクトにどのアクションができるか、典型的なものとして Read, Create, Write, Delete そして Administer を指定できます。ただし、あなたの好きなアクションを定義することもできます。

To learn about using ACLs in Grails, you can follow the Tutorial and in addition you can download and run a complete Grails application that uses the plugin.

チュートリアルを見ることで GrailsACL の使用について学ぶことができ、さらにプラグインを使用した Grails の完全なアプリケーションをダウンロードすることもできます。

Installing and running the application are described in Sample Application.

サンプルアプリケーションをインストールしてから実行してください。

In addition to this document, you should read the Spring Security documentation.

このドキュメントに加えて、 Spring Security のドキュメントも読むべきです。

KANJAVA PARTY の資料作ってる

土曜日はデモアプリのリファクタリングと草案の見直し。

日曜日は、 Qiita で下書きを書き始めた。
既に 40 ページ超えてて、普通にやったら 50 分に納まる気がしないけど、まぁ、とりあえず全部書いてリハーサルしてから考えよう。

あと LT の準備もせなあかんので、意外と時間が残っていない感。

KANJAVA PARTY 2017 の準備をちょっと進めた

KANJAVA PARTY 2017 で発表予定の内容について、ざっくり概要を少し進めた。

ひとまずざっくり概要は一通りできたので、次は全体を見直しながら内容の取捨選択をしていく。

JJUG CCC 2017 Spring と Java Day Tokyo 2017 に行ってきた

JJUG CCC 2017 Spring

見たのは次のセッション

  • 非機能要件と Spring Boot (梅澤雄一郎さん)
  • Vue.js + Spring Boot で楽しくフルスタック開発やってみた (うらがみさん)
  • データ履歴管理のためのテンポラルデータモデルと Reladomo の紹介 (伊藤博志さん)
  • 文型さえおさえれば英語を読む力は上がる! (よこなさん)
  • Selenide を使ってみた ~ブラウザテスト自動化~ (snowhiroさん)
  • Java で実装して学ぶ OAuth2.0! (多田真敏さん)
  • Java とアイドルのコラボ!?某アイドルBot開発の裏側 (菊田洋一さん)
  • Java チョットデキルへの道 ~Java コアSDKに見る真似したいコード10選~ (福嶋航さん)
  • VM の歩む道。Dalvik、ART、そして Java VM (yy_yankさん)

以下、雑に感想メモ。

非機能要件と Spring Boot (梅澤雄一郎さん)

  • 非機能要求グレード
    • 存在は知っていたが実際に使っているという話を聞けて「おー、やっぱり使えるんだなぁ」と思った
  • Spring Boot Acutuator
    • 面白そうと思ったけど、話の中でも出たように pull 型(こっちから情報の出力を指示しないといけない)なので本気で運用に組み込むのはいろいろ準備が必要そう
    • ただ、存在を知っておけば、いざというときに使えるときが来るかもしれない
  • Spring Security
    • 自分でもいろいろ調べているけど、知らない設定方法とかがあったのでまだまだ勉強不足を感じた
    • TERASOLUNA による拡張というのは考慮したことがなかったので、何か困ったときに TERASOLUNA拡張機能を調べるという選択肢もアリかなと思った

Vue.js + Spring Boot で楽しくフルスタック開発やってみた (うらがみさん)

  • サーバーサイドレンダリングはもう要らない
    • 自分はまだその域には達していない感
    • AngularJS, Knockout, Backbone とクライアントサイドをいろいろ触って、結局クライアントサイドは少なくしたいなぁと最近思ってる
    • でも、そういう考え方もあるのかぁ、と思えておもしろかった
  • Vue.js
    • データバインディングに特化したフレームワークということで、導入の敷居は低そう
    • webpack と gradle の組み合わせの話は、個人的に他の人がどうしているのかというのを聞いたことがなかったので、聞けて良かった(あぁ、やっぱり src/main/js にするのかぁ、とか)

データ履歴管理のためのテンポラルデータモデルと Reladomo の紹介 (伊藤博志さん)

  • データの履歴を記録する方法を4つに分類した話
    • データの履歴保存は現在の案件でも使っているが、ここで話されたような分類はとくにしていなかったので、純粋に興味深かった
  • データの更新を履歴として残すこと
    • 個人的に、「CQRS Documents by Greg Young」の「Events as a Storage Mechanism」につながる気がしている
    • DDD の集約内部の更新を実現するための手段として、 JPA のような FW を使うか、データの変更を UPDATE ではなく更新履歴として残す2通りの方法があると思っているが、この Reladomo を使えば後者の方法を自然な感じで実現できるのではないかという気がした
  • ただ、開発中とかにちょっと SQL でデータ検索するのが大変そうな気がするけど、それは慣れ次第だろうか

文型さえおさえれば英語を読む力は上がる! (よこなさん)

  • 自分が英文を読むときは主語がどれかくらいしか見てなくて、ほとんど雰囲気で英文を読んでいたので終始耳が痛かった
  • 「動詞が三人称単数形だから、主語は直前の●●ではなく、こっちの△△」という発想は全然なかったので、今後英文を読むときは意識してみようと思った

Selenide を使ってみた ~ブラウザテスト自動化~ (snowhiroさん)

  • Web 上の紹介記事とかは見てたことはあったが、触ったこともなくてほとんど忘れていたので聞いてみた
  • パッと見、 jQuery ができたら使えそうな感じがした
  • 今まで動いていたのに Chrome の自動アップデートでドライバが対応しなくなってテストが死ぬという話は、実際に手を出す前に知ることができて非常に良かった

Java で実装して学ぶ OAuth2.0! (多田真敏さん)

  • 今やってる Spring Security の勉強の延長で、いずれ OAuth2.0 にも触れることにもなる気がしていたので、基礎を学ぶために聞いてみた
  • 結論をいうと、完全には理解できなかった
  • けど、どこを注意すべきか、どこがややこしいかは多田さんが念入りに説明してくれていたので、改めて自習するときにはきっと役立つと思った

Java とアイドルのコラボ!?某アイドルBot開発の裏側 (菊田洋一さん)

  • 趣味全開の菊田さんのセッションを聞くのは初めてでしたが、とても面白かったです
  • LINE 用の Java ライブラリが公式から出ているということで、導入はすごい楽そうに感じた
  • ただ、とくに LINE を使って作りたいものが思いつかないのが最大の関門
  • 誰かが言っていたけど、作りたいものがあるって羨ましい

Java チョットデキルへの道 ~Java コアSDKに見る真似したいコード10選~ (福嶋航さん)

  • JDK のコア API のソースは半分がコメント
  • 一見すると意味が分からないコードも、コメントがあるおかげで意図が分かるようになっている
  • コメントの正しい使い方って感じがした
  • パフォーマンスについては、本当にシビアなとき以外は下手に参考にすると可読性を落としそうな気がした
    • ただ、そういうパフォーマンス向上のための手法があるということは勉強になった
      インスタンス変数へのアクセスはオーバーヘッドがあるので、回数が少ないほうがパフォーマンスは上がる、とか

VM の歩む道。Dalvik、ART、そして Java VM (yy_yankさん)

  • HotSpot と ART の違いについては、 ART のほうが API の数が少ない、実行ファイルが dex っていうちょっと特殊なやつ、くらいにしか思ってなかった
  • HotSpot はスタックマシン、 ART は特殊なレジスタマシンという違いがあるという話は初めて知った
  • VM についてチョットクワシクなれた気がする

Java Day Tokyo 2017

前後は普通にお仕事だったので、無理せず午後から参加して即日帰阪する感じになり、話を聞けたのは3つだけでした。

MicroProfileで広がるマイクロサービスの世界(数村憲治さん、吉富剛さん)

  • MicroProfile という存在は知っていたものの、背景とか今後の展望とかよくわかってなかったことが多かったので、聞いてみた
  • その辺はひとまず知ることができた気がする
  • ただ、4半期に1回リリースって、本当にそんなことできるんやろうか、
    とか、その後 JSR にするって果たしてスムーズに進むんやろうか
    といった不安?は残ったが。。。

Servlet 4.0 で始めるHTTP/2(柳原伸弥さん)

  • HTTP/2 がよくわかってなかったので、どんなことが変わるのかなぁという気持ちで聞いてみた
  • Server Push については、1回のリクエストに対して複数のレスポンスを返すことができるようになってる、ってことであってるのかな
  • 追加される APIOptional じゃなくて null を返すということが気になって、後半ちゃんと聞けてなかった

緊急開催!Java技術メモ三銃士が語るエンジニア道(ひしだまさん、かずひらさん、自分?!)

4回目の参加にして、まさかの登壇者側での参加になりました。

お話を頂いたのはたぶん1か月くらい前でした。
仕事帰りにいつもの感じでスマホを確かめたら、なぜか面識ゼロのいとうちひろさんから DM が届いていました。内容を見て、職場だったのにも関わらず驚いて声を上げてしまい、他の人に心配されました。

本当、他のメンバーの方々に比べて自分なんかが出るなんて恐れ多くて、参加するか悩みました。
しかし、 JDT に登壇者側で出るなんてこの機会を逃したら今後二度とないだろうし、やらずに後悔するよりかはやって後悔しようと思い、参加を決めました。

緊張とか不安とかでなんか変なこと言ってたかもしれませんが、大目に見てやってください。

特に最後の「エンジニアとして成長するには、どうしたらいいですか?」については、自分は回答する予定はなかったのですが、流れで回答することになってなんだか何を言ってるか分からなくなってた気がします。 エンジニアとして成長する方法とか僕が知りたいです

自分の場合、最初は単純に「知識のない今のままじゃエンジニアとしてこの先生きのこれない」と思ってがむしゃらに色々調べてたら、徐々に「新しいことを知ること」「知識が蓄えられて自分の技術力が上がること」に楽しさを見出すようになって、気付いたら仕事に関係なく興味を持ったことを手あたり次第調べるようになっていた、って感じなので、まぁ無理せず、技術を学ぶことに楽しさを見いだせれば良いのではないかなぁと思います(こういう感じのことを言いたかったけど、そう言えていた気がしない)。

Spring Security を調べるのに5ヶ月以上もかかってしまっているのも、「無理せず」の現れだと思います。
実際は1、2週間単位で全然別のことしてたり、本当に1日1オプションしか調べてないようなときもあるので、5ヶ月間みっちり取り組んでいるわけでもないです(逆に脳から変な汁が出てるときは、1日中みっちりやってるときもありますが)。
これから6月末までは KANJAVA PARTY の資料作りを優先するでしょうし、まだまだ終わらなさそうです。

とにもかくにも、 JDT に登壇という貴重な経験をすることができ、とてもいい思い出になりました。ありがとうございました!

スペシャルパネルセッション - 海外Javaコミュニティ・エンジニアは今どんな活動をしているのか?

  • 上述の登壇による疲れにより、ほとんど話は聞けず。。。申し訳ございません。。。