Spring Security 〜LDAP編〜

◆ Live配信スケジュール ◆
サイオステクノロジーでは、Microsoft MVPの武井による「わかりみの深いシリーズ」など、定期的なLive配信を行っています。
⇒ 詳細スケジュールはこちらから
⇒ 見逃してしまった方はYoutubeチャンネルをご覧ください
【4/18開催】VSCode Dev Containersで楽々開発環境構築祭り〜Python/Reactなどなど〜
Visual Studio Codeの拡張機能であるDev Containersを使ってReactとかPythonとかSpring Bootとかの開発環境をラクチンで構築する方法を紹介するイベントです。
https://tech-lab.connpass.com/event/311864/

Spring Security 〜基本編〜ではオンメモリにユーザー情報を格納していました。本稿ではLDAPを用いた認証を紹介します。
ログインが成功したときや失敗したときの処理を記述するハンドラについても紹介します。

下に掲載するMainSecurityConfigurerクラス以外の部分はSpring Security(基本)と同じです。

セキュリティ設定

Spring Securityの主要部部であるMainSecurityConfigurerクラスにLDAPによる認証を指定します。

  • MainSecurityConfigurer.java
package com.sios.ex.springsecurity;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.https.HttpServletRequest;
import javax.servlet.https.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

@Configuration
@EnableWebSecurity
public class MainSecurityConfigurer extends WebSecurityConfigurerAdapter {

	private static final Logger logger = LoggerFactory.getLogger(MainSecurityConfigurer.class);
	
	private static class AuthenticationSuccessHandlerImpl implements AuthenticationSuccessHandler {

		@Override
		public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
				Authentication authentication) throws IOException, ServletException {
			String username = request.getParameter("username");
			logger.debug("onAuthenticationSuccess:username=" + username);
			response.sendRedirect("/top");
		}

	}
	
	private static class AuthenticationFailureHandlerImpl implements AuthenticationFailureHandler {

		@Override
		public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
				AuthenticationException exception) throws IOException, ServletException {
			String username = request.getParameter("username");
			logger.debug("onAuthenticationFailure:username=" + username);
			response.sendRedirect("/login?error");
		}

	}

	@Override
	public void configure(WebSecurity web) throws Exception {
		// セキュリティ設定を無視するリクエスト設定
		// 静的リソースに対するアクセスはセキュリティ設定を無視する
		web.ignoring().antMatchers("/css/**", "/img/**", "/js/**");
	}

	@Override
	protected void configure(HttpSecurity https) throws Exception {
		https
			.authorizeRequests()
				// アクセス権限の設定
				// ログイン画面にはアクセス制限はなし
				.antMatchers("/login").permitAll()
				// その他は認証済みであること
				.anyRequest()
				.authenticated()
				.and()
			.formLogin()
				// ログイン画面
				.loginPage("/login")
				// 認証処理
				.loginProcessingUrl("/authenticate")
				// ログイン成功
				.successHandler(new AuthenticationSuccessHandlerImpl())
				// ログイン失敗
				.failureHandler(new AuthenticationFailureHandlerImpl())
				// usernameのパラメータ名
				.usernameParameter("username")
				// passwordのパラメータ名
				.passwordParameter("password")
				.and()
			.logout()
				// ログアウト処理
				.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
				// ログアウト成功時の遷移先
				.logoutSuccessUrl("/login")
				// ログアウト時に削除するクッキー名
				.deleteCookies("JSESSIONID")
				// ログアウト時のセッション破棄を有効化
				.invalidateHttpSession(true)
				.permitAll()
				.and()
			.sessionManagement()
				// セッションが無効な時の遷移先
				.invalidSessionUrl("/invalidSession");
	}
	
	@Autowired
	protected void config(AuthenticationManagerBuilder auth) throws Exception {
		auth.ldapAuthentication()
			.userDnPatterns("CN={0},CN=Users,DC=sample,DC=com")
			.groupSearchBase("CN=Users,DC=sample,DC=com")
			.contextSource()
			.url("ldap://sample.com:389")
			.managerDn("CN=admin,CN=Users,DC=sample,DC=com")
			.managerPassword("password");
	}

}

30~40行目

認証に成功したときに実行されるハンドラです。認証に成功するとonAuthenticationSuccessメソッドが呼び出されます。

42~52行目

認証に失敗したときに実行されるハンドラです。認証に失敗するとonAuthenticationFailureメソッドが呼び出されます。

78行目

認証に成功したときに呼び出されるハンドラを指定しています。defaultSuccessUrlとは同時に指定できません。ハンドラでリダイレクト先を指定します。

80行目

認証に失敗したときに呼び出されるハンドラを指定しています。defaultSuccessUrlとは同時に指定できません。ハンドラでリダイレクト先を指定します。

102~118行目

認証に使用するLDAPを設定しています。

アバター画像
About 武井 宜行 267 Articles
Microsoft MVP for Azure🌟「最新の技術を楽しくわかりやすく」をモットーにブログtech-lab.sios.jp)で情報を発信🎤得意分野はAzureによるクラウドネイティブな開発(Javaなど)💻「世界一わかりみの深いクラウドネイティブ on Azure」の動画を配信中📹 https://t.co/OMaJYb3pRN
ご覧いただきありがとうございます! この投稿はお役に立ちましたか?

役に立った 役に立たなかった

1人がこの投稿は役に立ったと言っています。


ご覧いただきありがとうございます。
ブログの最新情報はSNSでも発信しております。
ぜひTwitterのフォロー&Facebookページにいいねをお願い致します!



>> 雑誌等の執筆依頼を受付しております。
   ご希望の方はお気軽にお問い合わせください!

Be the first to comment

Leave a Reply

Your email address will not be published.


*


質問はこちら 閉じる