![[์ฝ์ง๋ก] Spring Security ์ธ์ฆ ๊ตฌํ ํ๊ณ insert ํ
์คํธ ์ค๋ฅ (AuditorAware)](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbozL7h%2FbtsJjnxY9fB%2FJseDpEy2AuVHozKYNChzw1%2Fimg.png)
[์ฝ์ง๋ก] Spring Security ์ธ์ฆ ๊ตฌํ ํ๊ณ insert ํ
์คํธ ์ค๋ฅ (AuditorAware)Back-end/Error2024. 8. 29. 15:19
Table of Contents
๐ ๋ฌธ์ ์ํฉ
spring security๋ก ์ธ์ฆ์ ๊ตฌํ ํ ๊ธฐ์กด์ Test๋ฅผ ๋๋ ธ๋๋ insert ์์ ์๋ฌ๊ฐ ๋ฐ์ํ๋ค.
๊ธฐ์กด ์ฝ๋
/*
๋จ์ ํ
์คํธ์์๋ spring ์ปจํ
์ด๋๋ฅผ ์ฌ์ฉํ๋ฉด ์๋๋ค.
@DataJpaTest: repository ๊ฐ์ฒด๋ฅผ ์์กด์ฃผ์
๋ฐ์ ์ ์๊ฒ ํด์ค๋ค. | @Transactional ์ ๊ฐ๊ณ ์์ด์ ํ
์คํธ ์ดํ ์๋ ๋กค๋ฐฑ ๊ฐ๋ฅ
*/
@DisplayName("JPA ์ฐ๊ฒฐ ํ
์คํธ")
@Import(JpaConfig.class)
@DataJpaTest
public class JpaRepositoryTest {
@Autowired private PostRepository postRepository;
@Autowired private PostCommentRepository postCommentRepository;
@Autowired private HashtagRepository hashtagRepository;
@Autowired private LikeRepository likeRepository;
@Autowired private PostHashtagRepository postHashtagRepository;
@Autowired private UserAccountRepository userAccountRepository;
@PersistenceContext
private EntityManager entityManager;
@DisplayName("insert ํ
์คํธ")
@Test
void givenTestData_whenInserting_thenWorksFine() {
// Given
long previousCnt = postRepository.count();
String username = "ella";
UserAccount userAccount = userAccountRepository.findById(username).orElseThrow();
Post post = Post.of(userAccount, "new post", "new content");
// When
postRepository.save(post);
// Then
assertThat(postRepository.count()).isEqualTo(previousCnt + 1);
}
}
@EnableJpaAuditing // @EnableJpaAuditing: JPA Auditing(๊ฐ์ฌ ๊ธฐ๋ฅ)์ ํ์ฑํ -> ์ํฐํฐ๊ฐ ์์ฑ๋๊ฑฐ๋ ์์ ๋ ๋, ์๋์ผ๋ก ๋ ์ง์ ์๊ฐ์ ๊ธฐ๋กํด์ค๋ค.
@Configuration
public class JpaConfig {
@Bean
public AuditorAware<String> auditorAware() {
//return () -> Optional.of("ella");
// ๊ธฐ์กด์ฝ๋์๋๋ฐ spring security ์ ์ฉ ํ ์๋์ ๊ฐ์ด ๋ณ๊ฒฝ๋จ
return () -> Optional.ofNullable(SecurityContextHolder.getContext())
.map(SecurityContext::getAuthentication)
.filter(Authentication::isAuthenticated)
.map(Authentication::getPrincipal)
.map(BoardPrincipal.class::cast) // .map(x -> (BoardPrincipal)x)
.map(BoardPrincipal::getUsername);
}
}
๋ฌธ์ ์์ธ
JpaConfig ์ AuditorAware<String>
: ํ์ฌ ๊ฐ์ฌ๋ฅผ ์ํํ๋ ์ฌ๋(๊ฐ์ฌ์)์ ์ด๋ฆ์ ์ ๊ณตํ๋ ์ธํฐํ์ด์ค
: ๊ฐ์ฌ๋ฅผ ์ํํ๋ ์ฌ๋์ ์ ๋ณด๋ฅผ ์ ๊ณตํจ์ผ๋ก์จ ๋๊ฐ ๋ฐ์ดํฐ๋ฅผ ์์ฑํ๊ณ ์์ ํ๋์ง ๊ธฐ๋กํ ์ ์๋ค.
→ ์คํ๋ง ์ํ๋ฆฌํฐ๋ก ์ธ์ฆ ๊ธฐ๋ฅ์ ๋ถ์ด๋ฉด์ ํด๋น ๋ถ๋ถ์ด ๋ณ๊ฒฝ๋จ
→ @DataJpaTest๋ ๊ธฐ๋ณธ์ ์ผ๋ก JPA์ ๊ด๋ จ๋ ์ค์ ๋ง ๋ก๋ํ๊ณ , Spring Security์ ๊ด๋ จ๋ ๋น์ด๋ ์ค์ ์ ๊ธฐ๋ณธ์ ์ผ๋ก ํฌํจ๋์ง ์๋๋ค!
⇒ SecurityContextHolder๋ฅผ ์ฌ์ฉํ๋ ์ฝ๋๊ฐ @DataJpaTest ํ๊ฒฝ์์ ์คํ๋ ๋ ๋ณด์ ์ปจํ ์คํธ(SecurityContext)๊ฐ ์ ๋๋ก ์ค์ ๋์ง ์์
⇒ AuditorAware์์ ๋ณด์ ์ปจํ ์คํธ๋ฅผ ์ฐธ์กฐํ๋ ์ฝ๋๋ null ๊ฐ์ ๋ฐํํจ
โ ํด๊ฒฐ
๋จ์ํ JPA ๊ธฐ๋ฅ์ ํ ์คํธํ๋ ค๋ ๊ฒฝ์ฐ์ด๋ฏ๋ก,
@DataJpaTest์์ ๋ณด์ ์ปจํ ์คํธ์ ์์กดํ์ง ์๋ ์ฝ๋๋ฅผ ์ฌ์ฉํ์→ jpa์์ ์ค๋ํ ์์ security๋ก๋ถํฐ์ ์ํฅ์์ ์์ ๋ก์์ง ์ ์๊ฒ
๋ฐ๋ก auditorAware๋ฅผ ํ ์คํธ ์ ์ฉ config๋ก ๋ฑ๋กํด์ ์ฌ์ฉํ์
- @Import(JpaConfig.class) → @Import(JpaRepositoryTest.TestJpaConfig.class)
- TestJpaConfig๋ฅผ ์๋์ ์ถ๊ฐ
/*
๋จ์ ํ
์คํธ์์๋ spring ์ปจํ
์ด๋๋ฅผ ์ฌ์ฉํ๋ฉด ์๋๋ค.
@DataJpaTest: repository ๊ฐ์ฒด๋ฅผ ์์กด์ฃผ์
๋ฐ์ ์ ์๊ฒ ํด์ค๋ค. | @Transactional ์ ๊ฐ๊ณ ์์ด์ ํ
์คํธ ์ดํ ์๋ ๋กค๋ฐฑ ๊ฐ๋ฅ
*/
@DisplayName("JPA ์ฐ๊ฒฐ ํ
์คํธ")
@Import(JpaRepositoryTest.TestJpaConfig.class) //๐๐๐
@DataJpaTest
public class JpaRepositoryTest {
@Autowired private PostRepository postRepository;
@Autowired private PostCommentRepository postCommentRepository;
@Autowired private HashtagRepository hashtagRepository;
@Autowired private LikeRepository likeRepository;
@Autowired private PostHashtagRepository postHashtagRepository;
@Autowired private UserAccountRepository userAccountRepository;
@PersistenceContext
private EntityManager entityManager;
@DisplayName("insert ํ
์คํธ")
@Test
void givenTestData_whenInserting_thenWorksFine() {
// Given
long previousCnt = postRepository.count();
String username = "ella";
UserAccount userAccount = userAccountRepository.findById(username).orElseThrow();
Post post = Post.of(userAccount, "new post", "new content");
// When
postRepository.save(post);
// Then
assertThat(postRepository.count()).isEqualTo(previousCnt + 1);
}
// ๐๐๐
// insert test์ auditing ๋ฌด์ํ๋๋ก
@EnableJpaAuditing
@TestConfiguration // ๋น์ผ๋ก ๋ฑ๋กํ๋, ํ
์คํธํ ๋๋ง ๋น์ผ๋ก ๋ฑ๋กํด๋ผ
// jpa์์ ์ค๋ํ
์์ security๋ก๋ถํฐ์ ์ํฅ์์ ์์ ๋ก์์ง ์ ์๊ฒ ๋ฐ๋ก auditorAware๋ฅผ ํ
์คํธ ์ ์ฉ config๋ก ๋ฑ๋กํด์ ์ฌ์ฉ
static class TestJpaConfig {
@Bean
AuditorAware<String> auditorAware() {
return () -> Optional.of("ella");
}
}
}