33
37

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Spring Security(+ MVC) JavaConfig

Last updated at Posted at 2014-06-24

#概要

Spring SecurityとSpring MVCをxmlを使わずに設定してみた際のメモ。

完全なソースはGutHub

#設定内容

  • 認証エラーの場合はログインページを表示する
  • 但し、Ajaxリクエストの場合はHTTPステータス401を返す
  • Thymeleafでsec:authorize="hasRole('ROLE_ADMIN')"のように、ロールによって表示を切り替えられるようにする

#必要な依存関係

使用する主なモジュールとバージョン

  • SpringSecurity : 4.0.0.M1
  • SpringMVC : 4.0.5.RELEASE
  • Thymeleaf : 2.1.3.RELEASE

詳細はpom.xmを参照

#SpringSecurityの設定

今回はAjaxリクエストの場合はログインページにリダイレクトするのではなくて、HTTPステータス401を返したいので、リクエストヘッダにX-Requested-With: XMLHttpRequestがあった場合のAuthenticationEntryPointを追加しています。

WebSecurityConfig
@Configuration
@EnableWebMvcSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

	@Override
	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
		auth.inMemoryAuthentication()
			.withUser("admin").password("admin").roles("ADMIN").and()
			.withUser("user").password("user").roles("USER");
	}

	@Override
	protected void configure(HttpSecurity http) throws Exception {
		http
			.authorizeRequests()
				.antMatchers(
					"/",
					"/css/**",
					"/login",
					"/logout").permitAll()
				.anyRequest().authenticated()
				.and()
			.formLogin()
				.loginPage("/login")
				.and()
			.logout()
				.logoutRequestMatcher(logoutRequestMatcher())
				.invalidateHttpSession(true)
				.and()
			.csrf()
				.and()
			.exceptionHandling()
				.defaultAuthenticationEntryPointFor(
					ajaxAuthenticationEntryPoint(),
					ajaxRequestMatcher()
				);
	}

	@Bean
	public AuthenticationEntryPoint ajaxAuthenticationEntryPoint() {
	return new AuthenticationEntryPoint() {
		@Override
		public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
			response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
		}
	};
	}

	@Bean
	public RequestMatcher ajaxRequestMatcher() {
	return new RequestHeaderRequestMatcher("X-Requested-With", "XMLHttpRequest");
	}

	@Bean
	public RequestMatcher logoutRequestMatcher() {
	return new AntPathRequestMatcher("/logout");
	}

}

#SpringMVCの設定

リソースハンドラとビューを返すだけのコントローラーを追加しています。
それから@Import(ThymeleafConfig.class)でThymeleafの設定をインポート。

WebMvcConfig
@Configuration
@EnableWebMvc
@Import(ThymeleafConfig.class)
@ComponentScan(
		basePackageClasses = {AjaxTestController.class}
)
public class WebMvcConfig extends WebMvcConfigurerAdapter {

	@Override
	public void addResourceHandlers(ResourceHandlerRegistry registry) {
		registry.addResourceHandler("/css/**").addResourceLocations("/WEB-INF/views/css/");
	}

	@Override
	public void addViewControllers(ViewControllerRegistry registry) {
		registry.addViewController("/").setViewName("index");
		registry.addViewController("/login").setViewName("login");
		registry.addViewController("/member").setViewName("member");
	}
}

#Tymeleafの設定

ThymeleafとSpringSecurityを連携するためにSpringSecurityDialectを追加。
開発中はキャッシュされない方がいいのでresolver.setCacheable(false);
それから文字コードの設定は2箇所あるので注意。

ThymeleafConfig
@Configuration
public class ThymeleafConfig {

	private final String CHARACTER_ENCODING = "UTF-8";

	@Bean
	public ServletContextTemplateResolver templateResolver() {
		ServletContextTemplateResolver resolver
				= new ServletContextTemplateResolver();
		resolver.setPrefix("/WEB-INF/views/");
		resolver.setSuffix(".html");
		resolver.setTemplateMode("HTML5");
		resolver.setCharacterEncoding(CHARACTER_ENCODING);
		resolver.setCacheable(false);
		return resolver;
	}

	@Bean
	public SpringTemplateEngine templateEngine() {
		SpringTemplateEngine engine = new SpringTemplateEngine();
		engine.setTemplateResolver(templateResolver());
		engine.addDialect(springSecurityDialect());
		return engine;
	}

	@Bean
	public ThymeleafViewResolver thymeleafViewResolver() {
		ThymeleafViewResolver resolver = new ThymeleafViewResolver();
		resolver.setTemplateEngine(templateEngine());
		resolver.setCharacterEncoding(CHARACTER_ENCODING);
		return resolver;
	}

	@Bean
	public IDialect springSecurityDialect() {
		SpringSecurityDialect dialect = new SpringSecurityDialect();
		return dialect;
	}
}
33
37
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
33
37

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?