【SpringBoot】SpringSecurity独自認証する

SpringSecurityを独自認証する設定をまとめておきます。
Filter→Provider（認証）の順で認証を行う

### SpringSecurityの設定
Security全体の設定をまとめる。
```java:WebSecurityConfig
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

	/**
	 * 独自認証を設定
	 */
	@Configuration
	protected static class AuthenticationConfiguration extends GlobalAuthenticationConfigurerAdapter {

		@Autowired
		private WebAuthenticationProvider webAuthenticationProvider;

		@Override
		public void configure(AuthenticationManagerBuilder auth) throws Exception {
			auth.authenticationProvider(webAuthenticationProvider);
		}
	}

	/**
	 * Web Security設定
	 */
	@Override
	public void configure(WebSecurity web) throws Exception {
		web.ignoring().antMatchers("/css/**", "/img/**", "/js/**");
	}

	/**
	 * HTTP Security設定
	 */
	@Override
	protected void configure(HttpSecurity http) throws Exception {
		WebUsernamePasswordAuthenticationFilter filter = new WebUsernamePasswordAuthenticationFilter();
		// 独自フィルター作成
		filter.setAuthenticationManager(authenticationManager());
		filter.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/admin/auth", "POST")); // ログイン時URL
		filter.setAuthenticationSuccessHandler(new SimpleUrlAuthenticationSuccessHandler("/admin/top")); // 成功時URL
		filter.setAuthenticationFailureHandler(new SimpleUrlAuthenticationFailureHandler("/admin/login?error")); // 失敗時URL
		filter.setUsernameParameter("username"); // ユーザ パラメータ名
		filter.setPasswordParameter("password"); // パスワード パラメータ名

		http.authorizeRequests().antMatchers("/admin/login").permitAll().anyRequest().authenticated();
		http.addFilter(filter);
	}
}

```

### Filter設定

```java:WebUsernamePasswordAuthenticationFilter
public class WebUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter {

	@Override
	public Authentication attemptAuthentication(HttpServletRequest req, HttpServletResponse res)
			throws AuthenticationException {
		
		String user = req.getParameter("username");
		String password = req.getParameter("password");
		
		if(user == null) {
			user = "";
		}
		
		if(password == null) {
			password = "";
		}
	
        // トークンの作成
        UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(user, password);
        
        setDetails(req, authRequest);
        return this.getAuthenticationManager().authenticate(authRequest);
	}
}
```

### Provider設定
ここで独自の認証を行う。
```java:WebAuthenticationProvider

@Configuration
@EnableWebSecurity
public class WebAuthenticationProvider implements AuthenticationProvider {

	@Override
	public Authentication authenticate(Authentication auth) throws AuthenticationException {
		String user = auth.getPrincipal().toString();
		String password = auth.getCredentials().toString();
		
		if (ObjectUtils.isEmpty(user)) {
			throw new AuthenticationCredentialsNotFoundException("ユーザー名もしくはパスワードに誤りがあります。");
		}

		if (ObjectUtils.isEmpty(password)) {
			throw new AuthenticationCredentialsNotFoundException("ユーザー名もしくはパスワードに誤りがあります。");
		}
		
		if (!user.equals("user")) {
			throw new AuthenticationCredentialsNotFoundException("ユーザー名もしくはパスワードに誤りがあります。");
		}

		if (!password.equals("pass")) {
			throw new AuthenticationCredentialsNotFoundException("ユーザー名もしくはパスワードに誤りがあります。");
		}
		
        Collection<GrantedAuthority> authorityList = new ArrayList<>();
        authorityList.add(new SimpleGrantedAuthority("ROLE_ADMIN"));

		// トークンを返却
		return new UsernamePasswordAuthenticationToken(user, password,authorityList);
	}

	@Override
	public boolean supports(Class<?> token) {
		return UsernamePasswordAuthenticationToken.class.isAssignableFrom(token);
	}

}
```