LoginSignup
33
37

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