はじめに
業務に関わる学習の合間に、進めているアプリ作りの日記です。
1月16日より開始します。
学習の進度によっては、できない日もあります。
内容
①登録処理の確認メール受け取りをしていないアカウントにてorg.springframework.security.authentication.DisabledException: User is disabledが発生しログインできなくなる。
UserDetailsServiceにてUserを返す際に第3引数のenableがfalseになっている事で起きる。
UserDetails (spring-security-docs API) - Javadoc
enabled set to true if the user is enabled
上記例外が発生した際に、HTMLにて確認メールを再送信できるようにする。
下記コード追記で例外が発生。
<div th:if = "(${message} != null) || (${session[SPRING_SECURITY_LAST_EXCEPTION]} != null)">
<div th:if = "${message == '登録が完了しましたので、確認メールを送らせていただきました。有効期限は24時間です。' || session[SPRING_SECURITY_LAST_EXCEPTION] == 'org.springframework.security.authentication.DisabledException: User is disabled'}" >
<h3>登録後に確認メールが届かない際は、メール受信設定確認の上、こちらにメールアドレスを入力し再度送信してください。</h3>
<form th:action="@{/resendConfirmationEmail}" class="forSiteUser" method=post>
<input type="email" name=mail placeholder="メールアドレスはこちら">
<button >再送信</button>
</form>
</div>
</div>
Could not parse as expression:(${message} != null) || (${session[SPRING_SECURITY_LAST_EXCEPTION]} != null)
...
EL1001E: Type conversion problem, cannot convert from null to boolean
Tutorial: Using Thymeleaf (ja)
OGNL/SpringElのエンジンが処理する記法とThymeleafが処理する記法があり、両者ともに試すが不可。
・(${session[SPRING_SECURITY_LAST_EXCEPTION]}) != null は動作する。
・'a' == 'a'は動作する
・ " 'a' == 'a' || 'b' == 'b' "で不可。
→「or」演算子を使用して"('a' == 'a') or ('b' == 'b') "で解決。
修正後もorg.springframework.security.authentication.DisabledException: User is disabledについては一致しない。
→ThymeleafにOGNL式で評価できるString.containsを使う。
${#strings.contains(session[SPRING_SECURITY_LAST_EXCEPTION], 'org.springframework.security.authentication.DisabledException: User is disabled')}で動作した。
...例外を渡すより、messageSourceを使ってメッセージにしてしまった方が簡潔な気がする。
確認メール再送実装も...
該当のメールアドレスの確認用トークンが存在しない問題が発生。
いずれ実装しようと思っていた期限切れトークンの自動削除処理を見据えて、トークンの再発行処理も加える。
if(tokenRepository.findByUser(siteUser) == null) {
String token = UUID.randomUUID().toString();
createVerificationTokenForUser(siteUser, token);
}
...DBへの無駄な問い合わせが多い気もする。
まとめ
・#string等の式はOGNL式を使用する。
・ThymeleafはJavaと書き方が違う事もあるから都度ドキュメント確認。
・例外については、MessageSourceを使う事で冗長にならなくて済むから時間がある時に修正要。
以前、「Thymeleafの場合は、${_csrf.token}でCSRFトークンを取得できる」というのを試したが、動作しなかった。そこで、CSRFトークンをHttpServletRequestから抜き出していたが、誤った実装であった。
${_csrf.token}のみで取得できたので、各コントローラーを修正していく。
その前に...
現時点でHttpServletRequestから取得していたCSRFトークンだと403エラーがでた。
Resolved [org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' is not supported]
結果としては、Thymeleafの機能を用いたCSRFトークンの取得で改善した。
★今回は、正しい実装に戻して切り分ける方針で解決した。
具体的な原因については後日調べる予定。
CSRFトークンがリクエスト毎に変わっている。(CSRFトークンが発行されるタイミングと関わるFilterから調べる
以上、各Ajax通信している箇所についても同様の修正を行う。
関係のない話
ムエタイの退会手続きに行きました。
転職したら、柔道か柔術のいずれかに挑戦したいです。