SpringBootに用意された、高機能なセキュリティ機構「SpringSecurity」を使います。
STS3(3.9.6)+SpringBoot2.0+Tymeleaf3.0迄動作確認しています。
SpringSecurity
認証ができるだけではなく、導入するだけで、CSRF(クロスサイトリクエストフォージェリ)攻撃対策などのセキュリティ対策もやってくれる、とてもありがたい機能であります。
汎用的で様々な認証方法にも対応してくれたりします。
が、高機能で汎用的であるがゆえに、パッと見になんか難しげに見えます。
少なくとも、自分はそうでした。
なので、あれこれ欲張って書かずに、現実的に使いそうなところだけにポイントを絞って説明を書いておこうかなと思います。
なお、MAVENベースです。
あと、いろいろあるので、数回にわけて書くつもりです。
今回は、とりあえず一発目なので、SpringSecurityを動かすことと、ロール(権限)によってページの中で部分的に表示・非表示を切り替える方法を確認します。
とりあえず使うだけなら超簡単
pom,xmlに以下を追記します。
<dependencies>・・</dependencies>の間です。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.thymeleaf.extras</groupId> <artifactId>thymeleaf-extras-springsecurity4</artifactId> </dependency>
前者はSpringSecurityを使うための設定です。
後者は、thymeleafでSpringSecurityが管理するロール(権限情報)を参照することができるようにするための設定です。
これだけで、実行したときにデフォルトの認証ダイアログが開きます。
SpringBoot2.0.0の場合はこんな感じです。
まあ、簡単ですね。
でも、これではページ全体を表示させるか?させないか?だけです。
権限によって、部分的に表示・非表示を切り替える
実際のところ、ログインさせるなら、ログインユーザ名や権限名を表示したり、権限によって参照できる項目に制限をかけるとかができないと仕方がないです。
そういう時のために、「thymeleaf-extras-springsecurity4」があります。
前回作成した簡単なHTMLページに、権限によって表示を切り替える部分を追加してみます。
HTMLの変更部分です。
まず、ヘダーのところを以下のように書き換えます。
<html xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
これで、sec という命令が使えるようになります。
まず、ユーザ名を表示させてみます。
<p>ようこそ<span sec:authentication="principal.username"></span>さん</p>
次に権限によって、表示を切り替えてるのはこうします。
<div sec:authorize="hasRole('ADMIN')"> <p>今は<b>ADMIN</b>権限でログインしています。</p> </div> <div sec:authorize="hasRole('USER')"> <p>今は<b>USER</b>権限でログインしています。</p> </div>
上記だと、ADMIN権限の時と、USER権限の時で表示を切り替えるようにしてます。
これらを付け加えた、HTML全体です。
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Sample App</title> <link href="../static/css/styles.csss" th:href="@{/css/styles.css}" rel="stylesheet"/> </head> <body> <div class="box"> <h1>Video-id</h1> <form role="form" id="SongInputForm" action="/outpg01" th:action="@{/outpg01}" th:object="${songInputForm}" method="post"> <p>ようこそ<span sec:authentication="principal.username"></span>さん</p> <p>好きな曲を選んでください。</p> <p th:text="*{selectedItem}"></p> <select id="singleSelect" name="selectedItem"> <option value="">---</option> <option th:each="item : ${selectItems}" th:value="${item.key}" th:text="${item.value}" th:selected="${item.key} == *{selectedItem}">singleSelect</option> </select> <div sec:authorize="hasRole('ADMIN')"> <p>今は<b>ADMIN</b>権限でログインしています。</p> </div> <div sec:authorize="hasRole('USER')"> <p>今は<b>USER</b>権限でログインしています。</p> </div> <button type="submit">実行</button> </form> </div> </body> </html>
さてやってみます。
ユーザIDとパスワードと権限を設定する一番カンタンな方法。
それはプロパティファイル(application.properties)に書くことです。
例えば、以下のように書きます。
spring.security.user.name=user
spring.security.user.password=demo
spring.security.user.roles=USER
上記は、SpringBootが2.0.0である前提です。
ちなみに、1.5.4の時はこうでした。
security.user.name=user
security.user.password=demo
security.user.role=USER
この設定なら、Userに「user」、Passwordに「demo」と入力して、USER権限でログインできます。
表示されたページはこうです。
今度は、プロパティのロールをADMINに書き換えてみます。
spring.security.user.name=user
spring.security.user.password=demo
spring.security.user.roles=ADMIN
そしたら、ログイン後はこうなります。
もちろん、ひとつのIDに複数のロールを与えることもできます。
spring.security.user.name=user
spring.security.user.password=demo
spring.security.user.roles=USER,ADMIN
これで表示されるページはこうです。
ちゃんと機能してますね。
ちなみに、Userとかパスワードを間違えて入力した場合はこうなります。
なるほど・・
今回のまとめ
デフォルトログインページは「まあ、見づらい・・」です。
このデフォルトログインページを実際にそのまま使うことは、ほぼないですね。
今回のやり方は簡単ですけど、あまり実用的ではないです。
プロパティファイルだと、ユーザも一人しか設定できませんし。
なので、あとは設定を加えていって、ログインページを変更したり、DB認証をしたりとかして、実用的にしていくことになります。
でも、続きで書くと、長くなりすぎるので、次回にしときます。