LoginSignup

This article is a Private article. Only a writer and users who know the URL can access it.
Please change open range to public in publish setting if you want to share this article with other users.

More than 1 year has passed since last update.

apache.shiroについてまとめてみた

Last updated at Posted at 2020-09-03

shiroを使おう

公式HPトップ
個人的にこのページがおすすめ 【shiro.iniの書き方】

1.shiroとは

Javaの、セキュリティ関連の、フレームワークです。
つまりJavaでの開発時に、セキュリティ関連を簡単に扱いたい!って時に使えます。

セキュリティ関連とは、ログイン関係だったり、APIの認証など
主に認証、承認、暗号化、セッション管理を簡単に扱えるようにしてくれます。

2.つまり何ができる?

・ログイン時のパスワードの暗号化(正確にはハッシュ化)
・ログインし、セッションに情報を保持
・ユーザの権限をセッションに保持
・DBからユーザの役割コードを取得
・役割コードに基づき閲覧ページを制御
・APIでのBasic認証などを制御

などです
ざっくりですが、一般のWebアプリではこの辺がメインになるかと。
というかこの辺をメインにshiroが作られていると思いますたぶん。

ようは、ユーザ管理やAPI認証がとても楽になる、ということですね

3.どんな感じで使うの

基本的には、「shiro.ini」という設定ファイルに
設定を記述していきます。

以下、設定のイメージ(公式より)

shito.ini
# =======================
# Shiro INI configuration
# =======================

[main]
# Objects and their properties are defined here,
# Such as the securityManager, Realms and anything
# else needed to build the SecurityManager

[users]
# The 'users' section is for simple deployments
# when you only need a small number of statically-defined
# set of User accounts.

[roles]
# The 'roles' section is for simple deployments
# when you only need a small number of statically-defined
# roles.

[urls]
# The 'urls' section is used for url-based security
# in web applications.  We'll discuss this section in the
# Web documentation

mainには基本的な設定、例えば
・参照先のDB(DataSource)
・接続の設定(JdbcRealm)
・呼び出すSQL
・パスワードハッシュ化のクラス

usersはあまり使わないイメージですが、アカウント関連の設定みたいですね

rolesは役割の設定

urlsには、ページ閲覧の承認ですね。例えば
・A.htmlにはX権限とY権限が必要
・ログインにはX権限が必要
・Basic認証にはY権限が必要

などです
そして、iniファイルの設定として
jdbcRealmを、「DefaultJdbcRealm.java」クラスにしたとすると
実際に実装したDefaultJdbcRealm.javaの内容に基づいた機能が呼び出されるわけです

早い話が、「shiro.iniには鍵と、鍵を使う順番が書いてある」というイメージです
伝わりにくかったらすみません...

4.具体的にはどうやって使うの

お待ちかね具体例。
よく使うので、mainとurlsの2セクションを例に取ります

shiro.ini
[main]
# SHA-256のハッシュに関する設定。すなわち、パスワードハッシュ化、照合の設定
sha256Matcher = org.apache.shiro.authc.credential.Sha256CredentialsMatcher

# DB接続の設定
myRealm = com.company.security.shiro.DatabaseRealm
# DB接続のタイムアウト設定
myRealm.connectionTimeout = 30000
# DB接続のユーザ名
myRealm.username = jsmith
# DB接続のパスワード
myRealm.password = secret

# DB設定の、認証に使うクラスを$「クエリ」で設定
# 上でsha256MatcherをSha256CredentialsMatcher.javaにしているので
# Sha256CredentialsMatcher.javaが設定されることになる
myRealm.credentialsMatcher = $sha256Matcher

# shiroのセッションは、セキュリティマネージャという領域に格納される
# セキュリティマネージャ内の、セッションの、共通タイムアウト設定
securityManager.sessionManager.globalSessionTimeout = 1800000

テキスト内にだいたい書きましたが、補足として
・だいたいがshiroの用意したJavaクラスで大丈夫です
・なので公式のものをそのまま使えます
・Javaクラスの中の仕組みが知りたかったら、適当にどこかでインポートしてコード見れます

そして、独自でDB接続を用意したい場合は

独自shiro.ini
[main]
ds = org.apache.shiro.JndiObjectfactory
ds.requiredType = javax.sql.DataSource
ds.resourceName = オリジナルDBリソース名

jdbcRealm = 自身で用意したjdbcRealmのjavaクラスのフルパス
jdbcRealm.permissionsLookupEnabled = true
# ログイン認証時にはしらせるSQL, ?を引数として、オリジナルjdbcRealmのJavaクラス内でセットできる
jdbcRealm.authenticationQuery = "SELECT 項目 FROM テーブル WHERE 項目 = ? AND 項目 = ?"
jdbcRealm.userRolesQuery = "SELECT 項目 FROM テーブル WHERE 項目 = ?"
# 接続先DBを、上記で設定したdsにする
jdbcRealm.dataSource = $ds

# shiroならではのセキュリティマネージャって領域のDB接続も、今設定してるjdbcRealmにしちゃう
securitymanager.realms = $jdbcRealm
# パスワード一致不一致を確かめるものも設定
jdbcRealm.credentialsMatcher = $自分で設定したパスワード一致のやつ、上でいうsha256matcher

shiroの特徴として
セキュリティマネージャという領域があります
この中に、セッションだったりDBから取得した情報をいろいろ持っています
ハッシュ化のソルトなどもこの中に格納したりしていて

よく使うHttpSessionも、セキュリティマネージャの中に入れてあげることで
どの状態からでもget/setできます

また、
jdbcRealm.authenticationQuery = "SELECT 項目 FROM テーブル WHERE 項目 = ? AND 項目 = ?"
のように
引数に複数の値をセットしたい場合ですが
shiro既存のjdbcRealmでは
java標準のpreparedstatementを用いて、ResultSetを設定してSQLのクエリを生成しているのですが
既存では引数が1つしかありませんので、
jdbcRealmを既存のままSQLの?引数を2個以上にするとエラーになります

なので...
org.apache.shiro.realm.jdbc.JdbcRealm.javaクラスをextendsした独自のjdbcRealmクラスを作成し
protecrted Authorizationinfo doGetAuthorizationInfo(PrincipalCollection principals)をOverrideし
while文でPreparedStatementをセットしているメソッドの引数を増やします
(実際のコードは諸事情によりここには記載しません、ご了承ください)

続いてurlsに移ります。

公式のリファレンスが別ページに移動しているのでご参照あれ

shiro.ini
[urls]
/index.html = anon
/user/create = anon
/user/** = authc
/admin/** = authc, roles[administrator]
/rest/** = authc, rest

anonは制限なし
authcは標準で、ログインに成功した人、という設定にしてくれています
また
roles[administrator]
DB内に役割コードとして、文字列「administrator」を持っていたとして
ログインした人の役割として「administrator」を所持している場合のみ閲覧可能
ということです

別に文字列の内容は何でもいいので

shiro.ini
[urls]
/独自ページ.html = roles[独自権限]

とすれば、役割コードを取得するSQLで「独自権限」という文字列をSELECTできた場合に
独自ページ.htmlへの遷移が可能になるわけですね

また、/rest/**と指定できることからわかるように
遷移先のhtmlファイルをディレクトリごとの分けて整理することで
Aディレクトリ配下のページは権限ABディレクトリ配下のページは権限Bというように
一括で分類できるわけです

また、JSFではxhtml内で

shiro.xhtml
<shiro:hasRole name="auth"></shiro:hasRole>
<shiro:hasAnyRoles name="auth"></shiro:hasAnyRoles>

というようにくくることで
指定した権限を持っている場合のみ、その要素を表示
と制御できる

これにより、ページ遷移の制御+ページ内部の閲覧制御をこなすことができる
かなり楽にしてくれますね

以上が今回のまとめになります。
最後まで読んでいただき、ありがとうございました。
修正点があれば随時対応していきます!

0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up