0. 프로젝트 소개(Spring Security) 및 Security에 대하여
1. User Entity 생성(Spring Security)
2. User 회원가입 (Spring Secureity)
3.Jwt의 사용 이유 (Spring Security)
4. Authorization(인증)
- 4-0 Authorization(인증) - 프로세스 설명
- 4-1 Authentication(인증) - UserDetails, UserDetailsService 및 JwtService 생성
- 4-2 Authentication(인증) - UsernamePasswordAuthenticationfilter 생성
- 4-3 Authentication(인증) - CorsFilter(선택사항)
- 4-4 Authentication(인증) - SecurityConfig
5. Authorization(인가)
- 5-1 Authorization(인가) - Jwt 인가 관련 에러 처리
- 5-2 Authorization(인가) - Jwt 인가 서비스 로직 추가
- 5-3 Authorization(인가) - AuthorizationFilter 생성
- 5-4 Authorization(인가) - SecurityConfig에 인가 관련 method 추가
6. OAuth
- 6-0 OAuth에 대해서
- 6-1 OAuth 2.0 - 사전 설정
- 6-2 OAuth2.0 - DTO 설정
- 6-3 OAuth2.0 - OAuth2UserService
- 6-4 OAuth2.0 - OAuth2UserService
- 6-5 OAuth2.0 - 필터 생성 및 SecurityConfig 수정
OAuth2UserServiceImpl
@Service
@Slf4j
@RequiredArgsConstructor
public class OAuth2UserServiceImpl implements OAuth2UserService {
private final UserRepository userRepository;
@Override
public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
OAuth2UserService<OAuth2UserRequest, OAuth2User> delegate = new DefaultOAuth2UserService();
OAuth2User oAuth2User = delegate.loadUser(userRequest);
String registrationId = userRequest.getClientRegistration().getRegistrationId();
SocialType socialType = getSocialType(registrationId);
String userNameAttributeName = userRequest.getClientRegistration().getProviderDetails().getUserInfoEndpoint().getUserNameAttributeName(); // OAuth2 로그인 시 키(PK)가 되는 값
Map<String, Object> attributes = oAuth2User.getAttributes(); // 소셜 로그인에서 API가 제공하는 userInfo의 Json 값(유저 정보들)
OAuthAttributes oAuthAttributes = new OAuthAttributes();
oAuthAttributes = oAuthAttributes.of(socialType, userNameAttributeName, attributes);
User createdUser = getUser(oAuthAttributes, socialType); // getUser() 메소드로 User 객체 생성 후 반환
return new CustomOAuth2User(
Collections.singleton(new SimpleGrantedAuthority(createdUser.getUserRole())),
attributes,
oAuthAttributes.getNameAttributeKey(),
createdUser.getEmail(),
createdUser.getUserRole()
);
}
private SocialType getSocialType(String registrationId) {
if (String.valueOf(KAKAO).equals(registrationId.toUpperCase())) return KAKAO;
else if (String.valueOf(GOOGLE).equals(registrationId.toUpperCase())) return GOOGLE;
return NONE;
}
@Transactional
public User getUser(OAuthAttributes oAuthAttributes, SocialType socialType) {
User user = userRepository.findBySocialTypeAndSocialId(socialType, oAuthAttributes.getOAuth2UserInfo().getId()).orElse(null);
if (user == null) {
return createUser(socialType, oAuthAttributes);
}
if (user.getProfileUrl() != oAuthAttributes.getOAuth2UserInfo().getProfileUrl()) {
user.updateProfileUrl(oAuthAttributes.getOAuth2UserInfo().getProfileUrl());
}
if (user.getNickname() != oAuthAttributes.getOAuth2UserInfo().getNickname()) {
user.updateNickname(oAuthAttributes.getOAuth2UserInfo().getNickname());
}
return user;
}
private User createUser(SocialType socialType, OAuthAttributes oAuthAttributes) {
return userRepository.save(oAuthAttributes.toEntity(socialType, oAuthAttributes.getOAuth2UserInfo()));
}
}
loadUser
@Override
public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
OAuth2UserService<OAuth2UserRequest, OAuth2User> delegate = new DefaultOAuth2UserService();
OAuth2User oAuth2User = delegate.loadUser(userRequest);
String registrationId = userRequest.getClientRegistration().getRegistrationId();
SocialType socialType = getSocialType(registrationId);
String userNameAttributeName = userRequest.getClientRegistration().getProviderDetails().getUserInfoEndpoint().getUserNameAttributeName(); // OAuth2 로그인 시 키(PK)가 되는 값
Map<String, Object> attributes = oAuth2User.getAttributes(); // 소셜 로그인에서 API가 제공하는 userInfo의 Json 값(유저 정보들)
OAuthAttributes oAuthAttributes = new OAuthAttributes();
oAuthAttributes = oAuthAttributes.of(socialType, userNameAttributeName, attributes);
User createdUser = getUser(oAuthAttributes, socialType); // getUser() 메소드로 User 객체 생성 후 반환
return new CustomOAuth2User(
Collections.singleton(new SimpleGrantedAuthority(createdUser.getUserRole())),
attributes,
oAuthAttributes.getNameAttributeKey(),
createdUser.getEmail(),
createdUser.getUserRole()
);
}
- OAuth2 로그인 시 가장 먼저 실행되는 메소드이다.
프로세스
1. userRequest(유저의 정보가 담겨있음)를 통해 OAuth2User 타입의 변수를 선언해준다.
OAuth2UserService<OAuth2UserRequest, OAuth2User> delegate = new DefaultOAuth2UserService();
OAuth2User oAuth2User = delegate.loadUser(userRequest);
2. 소셜타입을 가져온다.
String registrationId = userRequest.getClientRegistration().getRegistrationId();
SocialType socialType = getSocialType(registrationId);
private SocialType getSocialType(String registrationId) {
if (String.valueOf(KAKAO).equals(registrationId.toUpperCase())) return KAKAO;
else if (String.valueOf(GOOGLE).equals(registrationId.toUpperCase())) return GOOGLE;
return NONE;
}
3. OAuthAttribute 선언 후 소셜타입에 맞는 변수를 선언해준다.(이전에 포스팅한 method)
OAuthAttributes oAuthAttributes = new OAuthAttributes();
oAuthAttributes = oAuthAttributes.of(socialType, userNameAttributeName, attributes);
4. getUser() 메소드로 User 객체 생성 후 반환
- 있으면 그대로 내보내고 없으면 생성 method 실행
User createdUser = getUser(oAuthAttributes, socialType);
@Transactional
public User getUser(OAuthAttributes oAuthAttributes, SocialType socialType) {
User user = userRepository.findBySocialTypeAndSocialId(socialType, oAuthAttributes.getOAuth2UserInfo().getId()).orElse(null);
if (user == null) {
return createUser(socialType, oAuthAttributes);
}
if (user.getProfileUrl() != oAuthAttributes.getOAuth2UserInfo().getProfileUrl()) {
user.updateProfileUrl(oAuthAttributes.getOAuth2UserInfo().getProfileUrl());
}
if (user.getNickname() != oAuthAttributes.getOAuth2UserInfo().getNickname()) {
user.updateNickname(oAuthAttributes.getOAuth2UserInfo().getNickname());
}
return user;
}
private User createUser(SocialType socialType, OAuthAttributes oAuthAttributes) {
return userRepository.save(oAuthAttributes.toEntity(socialType, oAuthAttributes.getOAuth2UserInfo()));
}
5. return 타입이 OAuth2User임으로 CustomOAuth2User 타입으로 secutiry session에 저장할 변수를 선언 후 반환
return new CustomOAuth2User(
Collections.singleton(new SimpleGrantedAuthority(createdUser.getUserRole())),
attributes,
oAuthAttributes.getNameAttributeKey(),
createdUser.getEmail(),
createdUser.getUserRole()
);
'SpringBoot Security' 카테고리의 다른 글
6-5 OAuth2.0 - 필터 생성 및 SecurityConfig 수정 (0) | 2023.08.27 |
---|---|
6-3 OAuth2.0 - OAuthAttribute (0) | 2023.08.27 |
6-2 OAuth2.0 - DTO 설정 (0) | 2023.08.24 |
6-1 OAuth 2.0 - 사전 설정 (0) | 2023.08.06 |
6-0 OAuth에 대해서 (0) | 2023.07.25 |