Spring Securityで、独自ユーザ情報を簡単にHTML上に表示する方法

こんにちは。 エキサイト株式会社の三浦です。

Spring Securityを使えば、Spring Bootで簡単にログイン機構を作ることができます。

今回はSpring Securityの一部機能を拡張し、独自のユーザ情報を簡単にHTML上に表示する方法を紹介します。

Spring Securityのデフォルトユーザ情報

Spring Securityでは、多くの場合デフォルトで以下の3つのユーザ情報を持つことになります。

  • ユーザ名(IDとして用いるもので、メールアドレス等を持たせることもできる)
  • パスワードのハッシュ値
  • 権限一覧

以下のようにすることで、Spring Securityにユーザ情報を渡すことができます。

package sample;

import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Service;

@Service
public class UserDetailsServiceImpl implements UserDetailsService {

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // ユーザ名からパスワードのハッシュ値や権限一覧を取得する
        // ここでは、passwordHash と roleList とする

        return new User(
                username,
                passwordHash,
                roleList
        );
    }
}

なお、返り値である User クラスは返り値の型として指定されている UserDetails インターフェースの実装クラスで、Spring Securityにおけるユーザを示しています。

渡した情報は、ThymeleafというHTMLテンプレートと、その拡張機能である thymeleaf-extras-springsecurity6 を使えば、以下のようにHTML上に表示できます。

<!DOCTYPE html>
<html xmlns:th="https://www.thymeleaf.org"
      xmlns:sec="https://www.thymeleaf.org/thymeleaf-extras-springsecurity6"
      lang="ja"
>

<body>
    <!-- Spring Securityからユーザ名を取得して表示する -->
    <div sec:authentication="name"></div>
</body>
</html>

実際の画面が以下になります。

なお今回は、ユーザ名としてメールアドレスを渡すようにしています。

想定通り、メールアドレスを画面上に表示することができました。

必要な情報がこれだけならいいのですが、場合によっては、例えば独自に定義したユーザコードなど、上記以外の情報もHTML上で使用したいこともあるでしょう。

Spring Securityでは、それも簡単に実装することができます。

独自のユーザ情報を表示する

まずは、独自のユーザ情報をSpring Securityに渡します。

今回は、 userCode という独自データを持たせることにします。

先程使っていたSpring SecurityデフォルトのUserクラスを拡張して、 userCode フィールドを持たせるようにします。

package sample;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.User;

import java.util.Collection;

public class UserWithCode extends User {
    private final String userCode;

    public UserWithCode(String username, String password, Collection<? extends GrantedAuthority> authorities, String userCode) {
        super(username, password, authorities);
        this.userCode = userCode;
    }

    public String getUserCode() {
        return userCode;
    }
}

そしてこれを返り値として返すようにします。

package sample;

import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Service;

@Service
public class UserDetailsServiceImpl implements UserDetailsService {

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // ユーザ名からパスワードのハッシュ値や権限一覧を取得する
        // ここでは、passwordHash と roleList とする

        return new UserWithCode(
                username,
                passwordHash,
                roleList
                "customUserCode"
        );
    }
}

これで、Spring Securityに独自情報である userCode を渡すことができました。

後はHTML上で以下のように参照するだけです。

<!DOCTYPE html>
<html xmlns:th="https://www.thymeleaf.org"
      xmlns:sec="https://www.thymeleaf.org/thymeleaf-extras-springsecurity6"
      lang="ja"
>

<body>
    <div sec:authentication="name"></div>

    <!-- 独自情報はprincipal内に保存されている -->
    <div sec:authentication="principal.userCode"></div>
</body>
</html>

無事表示できました!

最後に

画面の表示はもちろん、URLの組み立てや分岐などでも独自情報を使うことはあるかもしれません。

非常に便利な機能なので、ぜひ使っていきましょう!