SE_BOKUのまとめノート的ブログ

SE_BOKUが知ってること・勉強したこと・考えたことetc

SpringSecurity:ログアウトの実装と、コントローラクラス(Java)でログインユーザ情報を得る  SpringBoot/thymeleaf

 SpringBootの「SpringSecurityの使い方」は今回が一応ラストです。 

書くのは以下の2つです。

  • SpringSecurityにおけるログアウトの実装
  • Javaのコントローラクラス内でログイン中のユーザ情報を得る

 前者のログアウトの実装は絶対必要なものですし、後者も監査等のために、ログインユーザをログに残す場合には、必須です。

なお、STS3(3.9.6)+SpringBoot2.0+tymeleaf3.0迄動作確認しています。

f:id:arakan_no_boku:20190222012501j:plain

 

SpringSecurityにおけるログアウトの実装

 

SpringSecurityは「/logout」というパスに対してリクエストを送るだけで、ログアウト処理をやってくれます。 

ここで言うログアウト処理とは、ログインユーザの認証情報のクリアとセッションの破棄だけでなく、CSRF対策用トークンの破棄(行っている場合)とかまで含まれます。 

かつ、コントローラクラスすら不要です。 

正直、このデフォルトを使わない理由が思いつかないです。 

ということで、ソースです。 

まず、HTMLから。 

ログアウトを追加したいところに、以下を追加します。

<form role="form" id="logout" th:action="@{/logout}" method="post">
    <button type="submit">ログアウト</button>
</form>

 

これでログアウトのリクエストを行います。 

あとは、JAVAの設定クラスでログアウト処理を有効にします。 

configure(HttpSecurity web)メソッドに、以下を追加します。

web.logout().logoutSuccessUrl("/login").permitAll();

 ログアウトが成功した時に遷移するパス(ま・・普通 login・・)を指定するのと、logout()した時にログイン画面はすべてのユーザにアクセスOKにする・・感じです。 

それを加えたJAVA設定クラスの全体はこうなります。

 

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
	
	@Autowired
	private UserDetailsService userDetailsService;
	   
	@Override
	protected void configure(HttpSecurity web)throws Exception{
		
		web.formLogin().loginPage("/login").defaultSuccessUrl("/inpg01").failureUrl("/login-error").permitAll();
		web.authorizeRequests().antMatchers("/css/**", "/images/**", "/js/**").permitAll().anyRequest().authenticated();
		web.logout().logoutSuccessUrl("/login").permitAll();
	}
	
	@Autowired
	void configureAuthenticationManager(AuthenticationManagerBuilder auth) throws Exception{
		
		auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
		
	}
	
	@Bean
	PasswordEncoder passwordEncoder(){
		return new BCryptPasswordEncoder();
	}
}

 

ログアウト処理以外の設定については前回・前々回あたりを参照ください。

arakan-pgm-ai.hatenablog.com

arakan-pgm-ai.hatenablog.com

 

これでログアウトボタンが表示され、押すとログアウト処理が行われます。

 

Javaのクラス内でログイン中のユーザ情報を得る

 

ログイン中のユーザの情報をログ等に記録する。 

最近、監査が厳しくなっている業務アプリケーションでは必須です。 

なので、JAVAのコントロールクラス内で、ログイン中のユーザ情報を取得する方法もあわせて整理しておきます。 

SpringSecurityにおけるユーザ情報は、ようするに、UserDetaillsインタフェースの実装クラスの情報のことです。 

前回、Userdetailsインタフェースを「UserAccount」クラスで実施しています。 

だから、今回の例ではControllerクラスのメソッド内で、UserAccountクラスオブジェクトを取得して、その情報を使う・・ということになります。 

該当部分のソースだけを抜き出します。

	    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
	    if(authentication.getPrincipal() instanceof UserAccount){
	    	UserAccount user = UserAccount.class.cast(authentication.getPrincipal());
	    	model.addAttribute("userInfo", "現在ログインしているユーザ名:" + user.getUsername() + "をコントローラクラスから取得しました。");
	    }else{
	    	model.addAttribute("userInfo", "");
	    }	

 

上記では、UserAccountオブジェクトのusernameを取り出して組み立てた文字列を、「userInfo」にマッピングしてます。 

今回は、それをHTML側で以下のように受けて表示するだけですが、上記の情報をログに書いたりとかもできるのはわかりますね。

<p th:text="${userInfo}"></p>

 

まとめです。

 

とりあえず、これでSpringSecurityで認証して、ログイン情報を取得して、ログアウトする・・という一連の基本的なことはできます。 

4回に渡ってやっているので、過去3回分の関連記事を再掲しておきます。 

今回もいれた4回分でひとつの記事みたいなもんですので、できるだけ1回めから順番に見てもらえるとありがたいです。

 

1回め

arakan-pgm-ai.hatenablog.com

2回め

arakan-pgm-ai.hatenablog.com

3回め

arakan-pgm-ai.hatenablog.com

 

以上です。