Spring Security 〜LDAP編〜

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を設定しています。

ご覧いただきありがとうございます! この投稿はお役に立ちましたか?

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

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

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です