implementation 'org.springframework.boot:spring-boot-starter-security'
testImplementation 'org.springframework.security:spring-security-test'
WebSecurityConfigurerAdapter가 deprecated되어 더이상 사용 불가하게 됨에 따라 기존의 방식인 오버라이드 해서 사용하는것이 아닌 bean으로 등록하여 사용한다.
@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
return (web) -> web.ignoring().antMatchers("여기에 인증 무시할 경로 ex)/css...");
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/**").permitAll() // 모두 접근 허용
.antMatchers("/admin").hasRole("admin") // ROLE_admin 만 접근 허용
.antMatchers("/member").hasRole("member") // ROLE_member 만 접근 허용
.anyRequest().authenticated()
.and()
.formLogin() // 로그인 관련 설정
.loginPage("/member/signIn") //로그인 페이지
.loginProcessingUrl("/member/signIn") //로그인 form의 action url 기본값은 '/login'
.defaultSuccessUrl("/member/main") //로그인에 성공하면 이동할 페이지
.and()
.logout() // 로그아웃 설정
.logoutUrl("member/signOut") //로그아웃 form의 action url
.logoutSuccessUrl("/member/main") // 로그아웃 성공하면 이동할 페이지
.invalidateHttpSession(true) // 세션 관련
.and()
.exceptionHandling() // 예외 핸들러
.accessDeniedPage("/member/deniedPage"); // 권한없는 접근시 이동할 페이지
return http.build();
}
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration)
throws Exception {
return authenticationConfiguration.getAuthenticationManager();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Entity
@Table(name = "member_tbl")
@Builder
@Getter
@AllArgsConstructor
@NoArgsConstructor
public class Member extends TimeEntity implements UserDetails {
@Id
private String memberId;
private String password;
private String name;
@Column(unique = true)
private String phoneNumber;
@Enumerated(EnumType.STRING)
private Auth auth;
// 계정의 권한 목록 리턴
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
Set<GrantedAuthority> roles = new HashSet<>();
roles.add(new SimpleGrantedAuthority(auth.getValue()));
return roles;
}
// 아이디 반환
@Override
public String getUsername() {
return memberId;
}
// 비밀번호 반환
@Override
public String getPassword() {
return password;
}
// 계정의 만료 여부
@Override
public boolean isAccountNonExpired() {
return true;
}
// 계정의 잠김 여부
@Override
public boolean isAccountNonLocked() {
return true;
}
// 비밀번호 만료 여부
@Override
public boolean isCredentialsNonExpired() {
return true;
}
// 계정의 활성화 여부
@Override
public boolean isEnabled() {
return true;
}
}
@AllArgsConstructor
@Getter
public enum Auth {
Admin("ROLE_Admin"),
Member("ROLE_Admin"),
ProductManager("ROLE_Admin"),
MemberManager("ROLE_Admin");
private String value;
}
public interface MemberService extends UserDetailsService {
}
@Service
@RequiredArgsConstructor
public class MemberServiceImpl implements MemberService {
private final MemberRepository memberRepository;
// memberId를 가지고 db에서 값을 찾아옴, 자동으로 password를 비교해주는 기능이 있다
@Override
public UserDetails loadUserByUsername(String memberId) throws UsernameNotFoundException {
return memberRepository.findById(memberId)
.orElseThrow(() -> new UsernameNotFoundException("ID Not Found!!"));
}
}
}
회원가입시 비밀번호는 BCryptPasswordEncoder로 인코딩해서 저장하도록 한다.