Spring Security 実装サンプル

Spring Securityのチュートリアルをやってみたのでメモ。 最低限必要なものは主に3つ。

1. Spring Security設定クラス

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    public void configure(WebSecurity web) throws Exception {
        // 認可対象外の設定
        web.ignoring().antMatchers("/favicon.ico", "/css/**", "/js/**", "/img/**"); 
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {

        // mypage以下は認可対象とする。
        http.authorizeRequests()
                .antMatchers("/mypage**")
                .authenticated();

        // ログイン設定
        http.formLogin()
                .loginProcessingUrl("/login")
                .loginPage("/loginForm")
                .failureUrl("/loginForm?error")
                .defaultSuccessUrl("/", true)
                .usernameParameter("username")
                .passwordParameter("password");

        // 認証用cookie1ヶ月保持
        http.rememberMe()
                .tokenValiditySeconds(86400);

        // /logoutにpostするだけでログアウト
        http.logout()
                .logoutUrl("/logout**")
                .logoutSuccessUrl("/loginForm");
    }

    @Configuration
    static class AuthenticationConfiguration extends GlobalAuthenticationConfigurerAdapter {
        @Autowired
        AccountDetailsService accountDetailsService;

        @Autowired
        PasswordEncoder passwordEncoder;

        @Override
        public void init(AuthenticationManagerBuilder auth) throws Exception {
            auth.userDetailsService(accountDetailsService)
                    .passwordEncoder(passwordEncoder);
        }
    }

}

2. 認証オブジェクトクラス

public class AccountDetails implements UserDetails {
    private final User user;

    public AccountDetails(User user) {
        this.user = user;
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return AuthorityUtils.createAuthorityList("DEMO");
    }

    public User getUser() {
        return user;
    }

    @Override
    public String getPassword() {
        return user.getPassword();
    }

    @Override
    public String getUsername() {
        return user.getEmail();
    }

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        return true;
    }
}

3. 認証オブジェクト生成, チェッククラス

@Service
public class AccountDetailsService implements UserDetailsService {

    @Autowired
    AccountRepository accountRepository;

    @Autowired
    ExceptionProvider exceptionProvider;

    @Transactional(readOnly = true)
    public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
        return Optional.ofNullable(accountRepository.findOne(email))
            .map(AccountDetails::new)
            .orElseThrow(() -> new UsernameNotFoundException(
                "user specified by " + email + " is not found!"
            ));
    }
}