애플리케이션을 만들기 위해서는 보통 인증/인가 등의 보안이 필요합니다.
스프링 시큐리티는 스프링 기반의 애플리케이션을 위한 보안 솔루션을 제공합니다.
인증
웹에서 인증이란 해당 리소스에 대해서 작업을 수행할 수 있는 주체인지 확인하는 것
예를들어 커뮤니티 사이트에서 게시판의 글을 보는 것은 로그인을 하지않아도 되지만,
댓글을 작성하려면 로그인을 해야하기때문에 인증이라는 절차가 필요하다.
인가
인증 과정 이후에 일어나는 일로 커뮤니티를 관리하는 관리자 페이지에는 관리자만 접근할 수 있고
일반 사용자의 접근을 막아야한다. 이때 접근하는 사용자가 관리자 페이지 URL에 대해서 인가된
회원인지를 검사하는 것이다.
maven으로 security dependency를 추가하였다.
<!-- Spring Security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
localhost에 접근하면 스프링 시큐리티가 제공하는 로그인 페이지가 나온다.
스프링이 제공하는 기본 아이디는 user이고
비밀번호는 console창에 보여준다.
또한 SecurityConfig를 이용해 스프링 시큐리티를 설정해야한다.
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.formLogin()
.loginPage("/members/login")
.defaultSuccessUrl("/")
.usernameParameter("email")
.failureUrl("/members/login/error")
.and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/members/logout"))
.logoutSuccessUrl("/")
;
http.authorizeRequests()
.mvcMatchers("/css/**", "/js/**", "/img/**").permitAll()
.mvcMatchers("/", "/members/**", "/item/**", "/images/**").permitAll()
.mvcMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
;
//
// http.exceptionHandling()
// .authenticationEntryPoint(new CustomAuthenticationEntryPoint())
// ;
return http.build();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
fiterChain에서
- .loginPage : 로그인 페이지 URL
- .defaultSuccessUrl : 로그인이 성공하면 이동하는 URL
- .usernameParameter : 로그인 시 사용할 파라미터 이름
- .failureUrl : 로그인이 실패하면 이동하는 URL
- .logoutRequestMatcher : 로그아웃 URL
- .logoutSuccessUrl : 로그아웃 성공시 이동하는 URL
맨 아래 passwordEncoder는 password를 암호화해 DB로 전달한다.
@Service
@Transactional
@RequiredArgsConstructor
public class MemberService implements UserDetailsService {
private final MemberRepository memberRepository;
public Member saveMember(Member member) {
validateDuplicateMember(member);
return memberRepository.save(member);
}
private void validateDuplicateMember(Member member) {
Member findMember = memberRepository.findByEmail(member.getEmail());
if(findMember != null) {
throw new IllegalStateException("이미 가입된 회원입니다.");
}
}
@Override
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
Member member = memberRepository.findByEmail(email);
if(member == null) {
throw new UsernameNotFoundException(email);
}
return User.builder()
.username(member.getEmail())
.password(member.getPassword())
.roles(member.getRole().toString())
.build();
}
}
MemberService에서 UserDetailsService를 implements 하여
loadUserByUsername을 Override 해서 email로 User정보를 가져온 다음
로그인을 할 수 있다.
로그인 폼을 만들어 security를 이용해 로그인 로그아웃 기능을 사용할 수 있었다.
변구훈 님의 스프링 부트 쇼핑몰 프로젝트 with JPA로 공부했습니다.
'Spring' 카테고리의 다른 글
Swagger를 사용해보았다. (0) | 2022.09.01 |
---|---|
Spring Boot 초기 설정 (0) | 2022.08.18 |
자바 예외 이해 (0) | 2022.07.28 |
트랜잭션의 개념과 이해 (0) | 2022.07.24 |
Spring Boot 와 JWT (0) | 2022.07.20 |
댓글