Spring Securityでログイン処理を割と簡単に実装してみる


Spring-boot-securityを使うと比較的簡単に認証周りの実装ができるのでメモ。

手順

  1. 依存関係をPOMに追記
  2. 認証用のユーザーエンティティの用意
  3. UserDetailsServiceの実装
  4. SecurityConfigの設定

1.依存関係をPOMに追記

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-security</artifactId>
</dependency>

2.認証用のユーザーエンティティの用意

@Data
@Entity
@Table(name = "users")
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class UserDto {

	@Id
	@Column(name = "username")
	private String username;
	@Column(name = "password")
	private String password;

}

3.UserDetailsServiceの実装

org.springframework.security.core.userdetails.Userを継承したクラスを作成。
作成したUserDtoクラスとの紐づけを行う

public class LoginUserDetails extends User {

	private final UserDto user;

	public LoginUserDetails(UserDto user) {
		super(user.getUsername(), user.getPassword(), AuthorityUtils.createAuthorityList("ROLE_USER"));
		this.user = user;
	}

	public UserDto getUser() {
		return user;
	}

}

作成したLoginUserDetailsを取得するサービスを作成。
org.springframework.security.core.userdetails.UserDetailsServiceを実装

@Service
public class LoginUserDetailsService implements UserDetailsService {

	@Autowired
	private UserRepository rep;

	@Override
	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
		UserDto user = rep.findOne(username);
		if (Objects.isNull(user)) {
			throw new UsernameNotFoundException("User Not Found...");
		}
		return new LoginUserDetails(user);
	}

}

4.SecurityConfigの設定


@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

	@Override
	public void configure(WebSecurity web) throws Exception {
		web.ignoring().antMatchers("/webjars/**", "/css/**", "/img/**", "/js/**"); //トップページで読み込むリソースファイルへのアクセスを許可
	}

	@Override
	public void configure(HttpSecurity http) throws Exception {
		//認証なしでアクセスできるページの宣言(この記述だとhttp://{host}/ のみ)
		http.authorizeRequests().antMatchers("/").permitAll().anyRequest().authenticated(); 

		//login処理をメソッドチェーンで記述
		http.formLogin()
				.loginProcessingUrl("/doAuth") //認証アクション時のアクセス先
				.loginPage("/") //ログイン開始画面
				.failureUrl("/?error") //失敗時にどこに遷移するか
				.defaultSuccessUrl("/admin/", true) //ログイン成功時の遷移先
				.usernameParameter("username") //ユーザー名として飛んでくるパラメータ名
				.passwordParameter("password"); //パスワードとして飛んでくるパラメータ名

		//logout時の処理を宣言
		http.logout()
				.logoutRequestMatcher(new AntPathRequestMatcher("/logout**")).logoutSuccessUrl("/");
	}

	@Configuration
	static class AuthenticationConfig extends GlobalAuthenticationConfigurerAdapter {

		@Autowired
		private UserDetailsService userDetailsService;

		@Bean //パスワードの暗号化方式を宣言(平文でDBにパスワードを保存しないこと!)
		public PasswordEncoder passwordEncoder() {
			return new BCryptPasswordEncoder(); 
		}

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

	}

}

比較的簡単に、と書きましたが、結構難解ですね。
とはいえ自力でいろいろ実装するよりはるかに手数が少なく、かつ堅牢なものが組めます。


コメントを残す

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