Spring Securityを使っていてログイン中のユーザー情報を変更する機能ってあるじゃないですか。そうするときにどうするのか気になりまして。
SecurityContextを更新すれば良さそう
結論としてはSecurityContextのAuthenticationを更新すれば良さそうです。以下のstackoverflowの質問と回答が役に立ちました。
SecurityContextっていうのはログイン中のユーザー情報を保持するクラスでセッションごとに値を持っています。値もデフォルトの設定ではセッション似保存されるので、単にDBだけを更新したとしてもSecurityContextは更新されません。そこでSecurityContextも合わせて更新させないとおかしなことになってしまうということですね。
更新のやり方は色々とあるかと思いますが、 User
クラスを UserDetailsService
から返している場合にはこうなるんじゃないかなと。あくまでも一例になりますが。ここで UserEntity
というクラスがありますがこれはDBのテーブルと対応したクラスです。
private void updateSecurityContext(UserEntity userEntity) { UserDetails user = User.builder() .username(userEntity.getUsername()) .password(userEntity.getPassword()) .roles(userMapper.findRolesByUserId(userEntity.getId()).toArray(String[]::new)) .build(); SecurityContext context = SecurityContextHolder.getContext(); context.setAuthentication(new UsernamePasswordAuthenticationToken(user, user.getPassword(), user.getAuthorities())); logger.info("security context updated to {}", user); }
ソースコードの全量はこちら。