😱 다음 아키텍처를 살펴보고 시작해보자 (SpringBoot ver 2.7.18)
- 스프링 보안 인증 프로세스와 관련된 클래스 및 필터 목록을 보여주는 다이어그램
1. SecurityConfig.java
- 시큐리티 설정하기 (사용한 SpringBoot 버전 2.7.18)
@Configuration
@EnableWebSecurity // 스프링 시큐리티 필터가 스프링 필터체인에 등록됨
public class SecurityConfig {
@Bean
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
// 1. CSRF 해제
.csrf((csrfConfig) -> csrfConfig.disable())
// 2. 인증, 권한 필터 설정
.authorizeRequests(authorize -> authorize
.antMatchers("/user/**","/board/**").authenticated()
.antMatchers("/manager/**").access("hasRole('ADMIN') or hasRole('MANAGER')")
.antMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().permitAll())
// 3. Form 로그인 설정
.formLogin((formLogin) -> formLogin
.loginPage("/login")
.usernameParameter("username")
.passwordParameter("password")
.loginProcessingUrl("/loginProc") // 시큐리티가 대신 로그인 진행
.defaultSuccessUrl("/")) // 로그인 후 default 경로
return http.build();
}
}
2. loginForm
- 기본 로그인화면
<form action="/loginProc" method="POST">
<input type="text" name="username" id="username"/>
<input type="password" name="password" id="password"/>
<button>로그인</button>
</form>
3. PrincipalDetails.java
- 로그인 진행이 완료된다면 Security Session이 만들어진다
Security Session에 들어갈 수 있는 오브젝트 타입 → [Authentication] 타입
[Authentication] 안에 User정보가 있어야한다 → User오브젝트 타입 → [UserDetails] 타입 객체
(Security Session → Authentication → UserDetails)
- UserDetails를 implement하는 PrincipalDetails 클래스 생성
@Data
public class PrincipalDetails implements UserDetails {
private User user; // 콤포지션
private Map<String, Object> attributes;
public PrincipalDetails(User user) {
this.user = user;
}
// 해당 User의 권한을 리턴
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
Collection<GrantedAuthority> collect = new ArrayList<>();
collect.add(new GrantedAuthority() {
@Override
public String getAuthority() {
return user.getRole();
}
});
return collect;
}
@Override
public String getPassword() {
return user.getPassword();
}
@Override
public String getUsername() {
return user.getUsername();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
이제 PrincipalDetails(UserDetails)를 Authentication에 넣을 수 있다 → Authentication 객체 만들기
4. PricipalService.java
- Authentication 객체 만들기
시큐리티 설정(SecurityConfig)에서 loginProcessingUrl("/loginProc") 로그인요청이 오면
자동으로 [UserDetailsService]타입으로 IoC되어있는 loadByUsername 함수가 실행된다
@Service
public class PrincipalDetailsService implements UserDetailsService{
@Autowired
private UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// 로그인할 때 username이 존재하는지 확인
User userEntity = userRepository.findByUsername(username);
if(userEntity != null) {
return new PrincipalDetails(userEntity);
}
return null;
}
}
>> [Security Session { Authentication ( UserDetails ) } ]
5. UserRepository.java
- findByUsername(username)이란 함수가 없기 때문에 생성
public interface UserRepository extends JpaRepository<User, Integer>{
// SELECT * FROM user WHERE username =?1
public User findByUsername(String username);
}
>> 기본 로그인 세팅 완료
'개발 > SpringBoot' 카테고리의 다른 글
[SpringBoot] OAuth 로그인 - 1 사전 준비 (구글, 네이버, 카카오) (0) | 2024.02.14 |
---|---|
[SpringBoot] SpringSecurity - 2 로그인 실패 (0) | 2024.02.14 |
[SpringBoot] 썸머노트(summernote) - 3 이미지 S3 저장 (1) | 2024.02.13 |
[SpringBoot] 썸머노트(summernote) - 2 이미지 저장 (1) | 2024.02.13 |
[SpringBoot] 썸머노트(summernote) - 1 사용하기 (0) | 2024.02.13 |