티스토리 뷰
Spring Boot : Security DaoAuthenticationProvider 사용시 @Transactional 처리
Korean Eagle 2020. 5. 25. 05:211. Spring Boot와 Spring DATA를 사용하면 Repository 단에서 자동적으로 @Transactional이 붙는다.
2. 그래서 보통 Service단에서는 @Transactional를 사용할 필요가 없다.
3. 하지만, 두 개 이상의 Repository를 다루는 Service 메소드인 경우는 서비스 단에서 Transaional이 필요하다.
4. 아무 생각없이 Spring Boot가 해주겠지 하면 정상적으로 동작하지 않는다.
5. 이것이 왜 문제가 되냐면 일반적인 Spring boot Logging level이 info인데 이것과 관련된 문제가 발생했을 때는 debug level에서 로그가 나온다. 그래서 무슨 문제가 있는지 알 수가 없다.
6. Spring Security를 사용하는 경우 로그인 정보를 데이터베이스에서 읽어오는데 User정보와 Role 두가지가 필요하다.
7. UserDetailsService를 구현하는 loadByUsername에서 이 메소드를 구현해야 하는데, 이 메소드가 두 개 이상의 Repo를 사용하기 때문에 @Transactional이 없으면 동작하지 않는다.
8. 서비스 단에서 @Transactional을 처리하는 방법은 그냥 서비스 메소드에 Transaction을 사용하면 된다.
8-0 이렇게 하면 스프링이 알아서 Transaction 범위를 변경하여 서비스 단위에서 처리하게 된다.
8-1 아래처럼 loadUserByUsername 메소드만 뜬금없이 @Transactional이 붙어 있는 것 같은데 당연한 것이다.
8-2 스프링 부트가 편리하게 지원해 주는 것을 제대로 알고 사용해야 한다.
package pe.pilseong.crmserver.service;
import java.util.Arrays;
import java.util.stream.Collectors;
import javax.transaction.Transactional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import pe.pilseong.crmserver.dto.UserDTO;
import pe.pilseong.crmserver.entity.Role;
import pe.pilseong.crmserver.entity.User;
import pe.pilseong.crmserver.repository.RoleRepository;
import pe.pilseong.crmserver.repository.UserRepository;
@Service
public class UserServiceImpl implements UserService {
private static final Logger LOGGER = LoggerFactory.getLogger(UserServiceImpl.class);
@Autowired
private UserRepository userRepository;
@Autowired
private RoleRepository roleRepository;
@Autowired
private BCryptPasswordEncoder passwordEncoder;
@Override
@Transactional
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByUsername(username);
if (user == null) {
throw new RuntimeException("user not found");
}
return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(),
user.getRoles().stream().map(role-> new SimpleGrantedAuthority(role.getName())).collect(Collectors.toList()));
}
@Override
public void save(UserDTO userDTO) {
User user = new User();
user.setId(userDTO.getId());
user.setUsername(userDTO.getUsername());
user.setPassword(this.passwordEncoder.encode(userDTO.getPassword()));
user.setFirstName(userDTO.getFirstName());
user.setLastName(userDTO.getLastName());
user.setEmail(userDTO.getEmail());
Role role = this.roleRepository.findbyName("ROLE_EMPLOYEE");
user.setRoles(Arrays.asList(role));
userDTO.setRoles(Arrays.asList(role.getName()));
LOGGER.debug(user.toString());
this.userRepository.save(user);
}
}
'Spring > Spring Boot' 카테고리의 다른 글
Spring Boot : WebJars 사용하기 (0) | 2020.07.07 |
---|---|
Spring Boot : 내장 서버를 톰캣에서 제티로 변경하기 (0) | 2020.05.27 |
Spring Boot : RestTemplate + Thymeleaf with Java Config - CRUD 클라이언트 구현 (0) | 2020.05.24 |
Spring Boot : 기초지식 (0) | 2020.05.23 |
Spring Boot : Security 사용하기 기본 Configuration (0) | 2020.05.01 |
- Total
- Today
- Yesterday
- 도커 개발환경 참고
- AWS ARN 구조
- Immuability에 관한 설명
- 자바스크립트 멀티 비동기 함수 호출 참고
- WSDL 참고
- SOAP 컨슈머 참고
- MySql dump 사용법
- AWS Lambda with Addon
- NFC 드라이버 linux 설치
- electron IPC
- mifare classic 강의
- go module 관련 상세한 정보
- C 메모리 찍어보기
- C++ Addon 마이그레이션
- JAX WS Header 관련 stackoverflow
- SOAP Custom Header 설정 참고
- SOAP Custom Header
- SOAP BindingProvider
- dispatcher 사용하여 설정
- vagrant kvm으로 사용하기
- git fork, pull request to the …
- vagrant libvirt bridge network
- python, js의 async, await의 차이
- go JSON struct 생성
- Netflix Kinesis 활용 분석
- docker credential problem
- private subnet에서 outbound IP 확…
- 안드로이드 coroutine
- kotlin with, apply, also 등
- 안드로이드 초기로딩이 안되는 경우
- navigation 데이터 보내기
- 레이스 컨디션 navController
- raylib
- one-to-one
- login
- 설정
- Rest
- WebMvc
- Validation
- Many-To-Many
- XML
- MYSQL
- 하이버네이트
- 상속
- form
- spring boot
- Security
- Spring Security
- 외부파일
- 매핑
- jsp
- RestTemplate
- 스프링부트
- mapping
- Angular
- 스프링
- 자바
- one-to-many
- crud
- hibernate
- Spring
- 로그인
- 설정하기