【Java・SpringBoot】Springセキュリティ⑧ - 画面表示の認可

Springで、ログイン画面に入力されたID・パスワードをDBに確認し、ユーザーの権限で特定のURLへのアクセスを禁止する機能を簡単に作成しましょう〜♪<br>
これまでに、直リンク禁止やログイン機能の実装、エラーメッセージの日本語化、パスワードの暗号化、ログアウト機能を実装したので、
今回は、認可の機能のなかで、**URLでそもそもアクセスさせないという手段の他に、権限がなければ画面にアイテムを表示しない**という実装を行います★

#画面表示の認可
###htmlタグへの追加内容
* タイムリーフの拡張ライブラリを使用します
* `xmlns:sec="http://www.thymeleaf.org/thymeleafextrasspringsecurity4"`

###認可用のコード
* 権限によって表示・非表示を切り替えたい箇所に、以下のようなコードを追加
* `sec:authorize="hasRole('<権限>')"`
* sec:authorize属性を使うと、権限を持っているユーザーのみhtmlタグが表示されるようになります


```homeLayout.html
    <!-- 中略 -->

<html xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
      xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">

    <!-- 中略 -->

    <!-- ===== サイドバー ===== -->
    <div class="container-fluid">
        <div class="row">
            <div class="col-sm-2 sidebar">
                <ul class="nav nav-pills nav-stacked">
                    <li role="presentation">
                        <a th:href="@{'/userList'}">ユーザ管理</a>
                    </li>
                    <li role="presentation" sec:authorize="hasRole('ADMIN')">
                        <a th:href="@{'/admin'}">アドミン用画面</a>
                    </li>
                </ul>
            </div>
        </div>
    </div>

    <!-- 中略 -->
```

#一般ユーザーでログインしてホーム画面確認！
* http://localhost:8080/login
* 一般ユーザでログインすると、
    * ユーザーID：satou@xxx.co.jp
    * パスワード：password
* ホーム画面にはアドミン権限専用画面へのリンクがなくなっています！🙆‍♂️

![normal.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282755/cf215a8b-9f9b-82d7-1ff3-97503d0bdc18.png)

* ADMIN権限のユーザでログインすると、
* ホーム画面にアドミン権限専用画面へのリンクがあり、リンクに遷移できます〜^^🙆‍♂️💮
    * ユーザーID：yamada@xxx.co.jp
    * パスワード：password

![admin.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282755/8be1b565-4ce5-c4f7-6a23-e626e96afbc4.png)
![admin2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282755/9eba19a7-a683-cdb0-31f2-b6a7475f52fd.png)


#(参考)コード全文

```homeLayout.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
      xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">

<head>
    <meta charset="UTF-8"></meta>

    <!-- Bootstrapの設定 -->
    <link th:href="@{/webjars/bootstrap/3.3.7-1/css/bootstrap.min.css}" rel="stylesheet"></link>
    <script th:src="@{/webjars/jquery/1.11.1/jquery.min.js}"></script>
    <script th:src="@{/webjars/bootstrap/3.3.7-1/js/bootstrap.min.js}"></script>

    <!-- CSSの読込 -->
    <link th:href="@{/css/home.css}" rel="stylesheet"></link>

    <title>Home</title>
</head>
<body>
    <!-- ===== ヘッダー（ナビゲーションバー） =====  -->
    <nav class="navbar navbar-inverse navbar-fixed-top">
        <div class="container-fluid">
            <div class="navbar-header">
                <a class="navbar-brand" href="#">SpringSample</a>
            </div>
            <form method="post" th:action="@{/logout}">
                <button class="btn btn-link pull-right navbar-brand" type="submit">
                    ログアウト
                </button>
            </form>
        </div>
    </nav>
    <!-- ===== サイドバー ===== -->
    <div class="container-fluid">
        <div class="row">
            <div class="col-sm-2 sidebar">
                <ul class="nav nav-pills nav-stacked">
                    <li role="presentation">
                        <a th:href="@{'/userList'}">ユーザ管理</a>
                    </li>
                    <li role="presentation" sec:authorize="hasRole('ADMIN')">
                        <a th:href="@{'/admin'}">アドミン用画面</a>
                    </li>
                </ul>
            </div>
        </div>
    </div>
    <!-- ===== コンテンツ ===== -->
    <div class="container-fluid">
        <div class="row">
            <div class="col-sm-10 col-sm-offset-2 main">
                <div th:include="__${contents}__"></div>
            </div>
        </div>
    </div>
</body>
</html>
```

```sql:data.sql
/* ユーザーマスタのデータ（ADMIN権限） */
INSERT INTO m_user (user_id, password, user_name, birthday, age, marriage, role)
VALUES('yamada@xxx.co.jp', '$2a$10$xRTXvpMWly0oGiu65WZlm.3YL95LGVV2ASFjDhe6WF4.Qji1huIPa', '山田邪馬田', '1990-01-01', 28, false, 'ROLE_ADMIN');

/* ユーザーマスタのデータ（一般権限） */
INSERT INTO m_user (user_id, password, user_name, birthday, age, marriage, role)
VALUES('satou@xxx.co.jp', '$2a$10$xRTXvpMWly0oGiu65WZlm.3YL95LGVV2ASFjDhe6WF4.Qji1huIPa', '佐藤砂糖', '1999-01-01', 21, false, 'ROLE_GENERAL');
```