feat(customer-apigateway-service, user-servcie): customer gateway filter 추가

- customer gateway service에 jwt header filter 추가
- user-service에서 OAuth
service refactor
This commit is contained in:
hoon7566
2022-02-18 15:10:50 +09:00
parent e0455da9a3
commit 32e93aaad3
11 changed files with 322 additions and 100 deletions

View File

@@ -0,0 +1,94 @@
package com.justpickup.userservice.domain.jwt.service;
import com.justpickup.userservice.domain.user.dto.CustomerDto;
import com.justpickup.userservice.domain.user.dto.OAuthAttributeDto;
import com.justpickup.userservice.domain.user.entity.Customer;
import com.justpickup.userservice.domain.user.repository.CustomerRepository;
import com.justpickup.userservice.domain.user.repository.UserRepository;
import com.justpickup.userservice.domain.user.service.UserService;
import com.justpickup.userservice.domain.user.service.UserServiceImpl;
import com.justpickup.userservice.global.utils.JwtTokenProvider;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserService;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.core.user.DefaultOAuth2User;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
@Slf4j
@RequiredArgsConstructor
@Service
public class OAuthService implements OAuth2UserService<OAuth2UserRequest, OAuth2User> {
private final CustomerRepository customerRepository;
private final HttpServletResponse response;
private final HttpServletRequest request;
private final JwtTokenProvider jwtTokenProvider;
private final RefreshTokenService refreshTokenService;
private final UserServiceImpl userServiceImpl;
@Override
@Transactional
public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
OAuth2UserService<OAuth2UserRequest,OAuth2User> delegate = new DefaultOAuth2UserService();
OAuth2User oAuth2User = delegate.loadUser(userRequest);
//OAuth 서비스 id
String registrationId = userRequest.getClientRegistration().getRegistrationId();
//OAuth 로그인 진행시 키가 되는 필드값
String userNameAttributeName = userRequest.getClientRegistration()
.getProviderDetails()
.getUserInfoEndpoint()
.getUserNameAttributeName();
// OAuth2UserService
OAuthAttributeDto attributeDto = OAuthAttributeDto.of(registrationId, userNameAttributeName,oAuth2User.getAttributes());
Customer customer = saveCustomer(attributeDto);
// TODO: 2022/02/16 Response에 token 담아 보내기
String userEmail = customer.getEmail();
Collection<? extends GrantedAuthority> authorities = userServiceImpl.loadUserByUsername(userEmail).getAuthorities();
List<String> roles = authorities.stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList());
String accessToken = jwtTokenProvider.createJwtAccessToken(userEmail, request.getRequestURI(), roles);
String refreshToken = jwtTokenProvider.createJwtRefreshToken();
refreshTokenService.updateRefreshToken(customer.getId(), jwtTokenProvider.getRefreshTokenId(refreshToken));
response.setHeader("Access-token",accessToken);
response.setHeader("refresh-token",refreshToken);
return new DefaultOAuth2User(
authorities
, attributeDto.getAttributes()
, attributeDto.getNameAttributeKey());
}
@Transactional
public Customer saveCustomer(OAuthAttributeDto attributeDto){
return customerRepository.save(
customerRepository.findByEmail(attributeDto.getEmail())
.orElse(attributeDto.toEntity(attributeDto))
);
}
}

View File

@@ -3,6 +3,7 @@ package com.justpickup.userservice.domain.jwt.service;
import com.justpickup.userservice.domain.user.dto.JwtTokenDto;
public interface RefreshTokenService {
void updateRefreshToken(Long id, String uuid);
JwtTokenDto refreshJwtToken(String accessToken, String refreshToken);
void logoutToken(String accessToken);
}

View File

@@ -16,7 +16,6 @@ import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

View File

@@ -17,7 +17,7 @@ public class Customer extends User {
private AuthType oauthType;
public Customer(String email, String password, String name, String phoneNumber, AuthType oauthType) {
super(email, password, name, phoneNumber,null);
super(email, password, name, phoneNumber);
this.dtype = Customer.class.getSimpleName();
this.oauthType = oauthType;
}

View File

@@ -26,9 +26,6 @@ public abstract class User extends BaseEntity {
private String phoneNumber;
@Enumerated(EnumType.STRING)
private Role role;
@Column(insertable = false,updatable = false)
protected String dtype;

View File

@@ -1,16 +1,13 @@
package com.justpickup.userservice.domain.user.service;
import com.justpickup.userservice.domain.user.dto.CustomerDto;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserService;
import org.springframework.security.oauth2.core.user.OAuth2User;
import com.justpickup.userservice.domain.user.dto.StoreOwnerDto;
import com.justpickup.userservice.domain.user.entity.StoreOwner;
public interface UserService extends OAuth2UserService<OAuth2UserRequest, OAuth2User> {
public interface UserService {
void updateRefreshToken(Long id, String refreshToken);
CustomerDto findCustomerByUserId(Long userId);
StoreOwner saveStoreOwner(StoreOwnerDto storeOwnerDto);
}

View File

@@ -1,8 +1,6 @@
package com.justpickup.userservice.domain.user.service;
import com.justpickup.userservice.domain.jwt.utils.JwtTokenProvider;
import com.justpickup.userservice.domain.user.dto.CustomerDto;
import com.justpickup.userservice.domain.user.dto.OAuthAttributeDto;
import com.justpickup.userservice.domain.user.dto.StoreOwnerDto;
import com.justpickup.userservice.domain.user.entity.Customer;
import com.justpickup.userservice.domain.user.entity.StoreOwner;
@@ -12,28 +10,17 @@ import com.justpickup.userservice.domain.user.repository.CustomerRepository;
import com.justpickup.userservice.domain.user.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserService;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.core.user.DefaultOAuth2User;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
@Service
@RequiredArgsConstructor
@@ -44,9 +31,6 @@ public class UserServiceImpl implements UserService, UserDetailsService {
private final CustomerRepository customerRepository;
private final UserRepository userRepository;
private final PasswordEncoder passwordEncoder;
private final HttpServletResponse response;
private final HttpServletRequest request;
private final JwtTokenProvider jwtTokenProvider;
@@ -74,77 +58,8 @@ public class UserServiceImpl implements UserService, UserDetailsService {
String encode = passwordEncoder.encode(storeOwnerDto.getPassword());
StoreOwner storeOwner = new StoreOwner(storeOwnerDto.getEmail(), encode, storeOwnerDto.getName(),
storeOwnerDto.getPhoneNumber(), storeOwnerDto.getBusinessNumber(), storeOwnerDto.getRefreshTokenId());
storeOwnerDto.getPhoneNumber(), storeOwnerDto.getBusinessNumber());
return userRepository.save(storeOwner);
}
@Override
@Transactional
public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
OAuth2UserService<OAuth2UserRequest,OAuth2User> delegate = new DefaultOAuth2UserService();
OAuth2User oAuth2User = delegate.loadUser(userRequest);
//OAuth 서비스 id
String registrationId = userRequest.getClientRegistration().getRegistrationId();
//OAuth 로그인 진행시 키가 되는 필드값
String userNameAttributeName = userRequest.getClientRegistration()
.getProviderDetails()
.getUserInfoEndpoint()
.getUserNameAttributeName();
// OAuth2UserService
OAuthAttributeDto attributeDto = OAuthAttributeDto.of(registrationId, userNameAttributeName,oAuth2User.getAttributes());
Customer customer = saveCustomer(attributeDto);
// TODO: 2022/02/16 Response에 token 담아 보내기
String userEmail = customer.getEmail();
Collection<? extends GrantedAuthority> authorities = loadUserByUsername(userEmail).getAuthorities();
List<String> roles = authorities.stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList());
String accessToken = jwtTokenProvider.createJwtAccessToken(userEmail, request.getRequestURI(), roles);
String refreshToken = jwtTokenProvider.createJwtRefreshToken();
updateRefreshToken(customer.getId(), jwtTokenProvider.getRefreshTokenId(refreshToken));
customer.changeRefreshToken(refreshToken);
response.setHeader("Access-token",accessToken);
response.setHeader("refresh-token",refreshToken);
return new DefaultOAuth2User(
authorities
, attributeDto.getAttributes()
, attributeDto.getNameAttributeKey());
}
@Transactional
public Customer saveCustomer(OAuthAttributeDto attributeDto){
return customerRepository.save(
customerRepository.findByEmail(attributeDto.getEmail())
.orElse(attributeDto.toEntity(attributeDto))
);
}
@Transactional
@Override
public void updateRefreshToken(Long id, String refreshToken) {
User user = userRepository.findById(id)
.orElseThrow(() -> new NotExistUserException("사용자 고유번호 : " + id + "는 없는 사용자입니다."));
user.changeRefreshToken(refreshToken);
}
}

View File

@@ -1,5 +1,6 @@
package com.justpickup.userservice.global.security;
import com.justpickup.userservice.domain.jwt.service.OAuthService;
import com.justpickup.userservice.domain.jwt.service.RefreshTokenServiceImpl;
import com.justpickup.userservice.global.utils.JwtTokenProvider;
import com.justpickup.userservice.domain.user.service.UserService;
@@ -14,6 +15,7 @@ import org.springframework.security.config.annotation.web.configuration.WebSecur
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserService;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@Configuration
@@ -26,7 +28,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final RefreshTokenServiceImpl refreshTokenServiceImpl;
private final CookieProvider cookieProvider;
private final UserService userService;
private final OAuthService oAuthService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
@@ -52,7 +54,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
http.oauth2Login()
.defaultSuccessUrl("http://just-pickup.com:8000/customer-frontend-service/")
.userInfoEndpoint()
.userService(userService);
.userService(oAuthService);
http.addFilter(loginAuthenticationFilter);
http.addFilterBefore(new HeaderAuthorizationFilter(), UsernamePasswordAuthenticationFilter.class);