ThymeleafにSpringSecurity用のライブラリがあるということで使ってみました。
https://github.com/thymeleaf/thymeleaf-extras-springsecurity
このモジュールを追加するとThymeleafを使ってHTMLをレンダリングする際にSpringSecurityの Authentication
に簡単にアクセスすることができるみたいです。Authentication
はコントローラーから Model
に詰め込んで渡すこともできますがコントローラーの数が増えるほど重複したコードを書く必要が出てきてしまうので、コードを簡潔にする効果が期待できそうですね。
ライブラリの追加
ライブラリはMavenリポジトリから取得できます。執筆時点での最新のバージョンを取得したら以下のようになりました。
dependencies { implementation("org.springframework.boot:spring-boot-starter-web") implementation("org.springframework.boot:spring-boot-starter-security") implementation("org.springframework.boot:spring-boot-starter-thymeleaf") implementation("org.thymeleaf.extras:thymeleaf-extras-springsecurity5") }
thymeleaf-extras-springsecurity5
というのがそれですが、SpringSecurityのバージョンごとに対応したものがあるのでそれに合わせます。
使い方
ライブラリの使い方は以下のサイトで解説されています。
- https://github.com/thymeleaf/thymeleaf-extras-springsecurity
- https://www.thymeleaf.org/doc/articles/springsecurity.html
HTML内で使うには以下の宣言をすれば良さそう。 sec
プレフィックスで機能にアクセスできるようになります。
<html xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
属性へのアクセス
Authentication
の属性にアクセスするには以下のようにすればいいみたいです。直感的に書けますね。
<div sec:authentication="name"> Authenticationのname値に書き換わる </div>
name
が Authentication
の属性名となるので、ここを変えてあげれば他の属性にもアクセスすることができます。例えば独自の UserDetails
クラスを持っていてメールアドレスのフィールドがあるのであれば以下のようにすればいいはずです。
<div sec:authentication="mailAddress"> Authenticationのメールアドレスの値に書き換わる </div>
ロールへのアクセス
ユーザが保持するロールの有無で画面の表示内容を切り替えるということは多くの場面であると思いますが、以下のようにすればできるようです。
<div sec:authorize="hasRole('ROLE_ADMIN')"> ADMINロールを持っている場合のみ表示される </div>
sec:authorize
は実際にはSpringEL式を使っているようなので hasRole
以外のメソッドも同じようにして使用できるみたいです。公式のGitHubでは以下のように許可するロールを変数として追加して動的に表示内容を切り替えるやり方が解説されていました。
<div sec:authorize="${hasRole(#vars.expectedRole)}"> This will only be displayed if authenticated user has a role computed by the controller. </div>
#vars
というのはThymeleafの公式ドキュメントを見る限りコンテキスト変数の事なのでコントローラーから渡された値へのアクセスになるみたいですね。
https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf_ja.html#式基本オブジェクト
URLに基づいた制御
URLへの認可を判断して表示内容を切り替える事ができるみたいです。リンクの表示・非表示で使うと便利そうですね。
<div sec:authorize-url="/admin"> /admin へアクセスできる場合は表示される。 </div>
メソッドを指定すればGET以外でも使用できます。
<div sec:authorize-url="POST /admin"> /admin へPOSTリクエストを行える場合は表示される。 </div>