Merge branch 'oAuth-jwt' into feature/authentication

# Conflicts:
#	user-service/src/main/java/com/justpickup/userservice/domain/jwt/service/RefreshTokenServiceImpl.java
#	user-service/src/main/java/com/justpickup/userservice/domain/user/entity/User.java
#	user-service/src/main/java/com/justpickup/userservice/global/security/LoginAuthenticationFilter.java
#	user-service/src/main/java/com/justpickup/userservice/global/security/SecurityConfig.java
#	user-service/src/main/java/com/justpickup/userservice/global/utils/JwtTokenProvider.java
This commit is contained in:
hoon7566
2022-02-18 14:15:19 +09:00
8 changed files with 64 additions and 83 deletions

View File

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

View File

@@ -16,6 +16,7 @@ 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

@@ -16,9 +16,9 @@ public class Customer extends User {
@Enumerated(EnumType.STRING)
private AuthType oauthType;
public Customer(String email, String password, String name, String phoneNumber, AuthType oauthType) {
super(email, password, name, phoneNumber,Role.USER);
super(email, password, name, phoneNumber,null);
this.dtype = Customer.class.getSimpleName();
this.oauthType = oauthType;
}
}

View File

@@ -1,14 +0,0 @@
package com.justpickup.userservice.domain.user.entity;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@Getter
@RequiredArgsConstructor
public enum Role {
GUEST("ROLE_GUEST", "손님"),
USER("ROLE_USER", "일반 사용자");
private final String key;
private final String title;
}

View File

@@ -30,15 +30,7 @@ public abstract class User extends BaseEntity {
private Role role;
@Column(insertable = false,updatable = false)
private String dtype;
public User(String email, String password, String name, String phoneNumber, Role role) {
this.email = email;
this.password = password;
this.name = name;
this.phoneNumber = phoneNumber;
this.role = role;
}
protected String dtype;
public User(String email, String password, String name, String phoneNumber) {
this.email = email;

View File

@@ -9,6 +9,8 @@ import com.justpickup.userservice.domain.user.dto.StoreOwnerDto;
import com.justpickup.userservice.domain.user.entity.StoreOwner;
public interface UserService extends OAuth2UserService<OAuth2UserRequest, OAuth2User> {
void updateRefreshToken(Long id, String refreshToken);
CustomerDto findCustomerByUserId(Long userId);
StoreOwner saveStoreOwner(StoreOwnerDto storeOwnerDto);
}

View File

@@ -1,60 +1,54 @@
package com.justpickup.userservice.domain.user.service;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
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.dto.OAuthAttributeDto;
import com.justpickup.userservice.domain.user.dto.OAuthAttributeDto;
import com.justpickup.userservice.domain.user.entity.Customer;
import com.justpickup.userservice.domain.user.entity.StoreOwner;
import com.justpickup.userservice.domain.user.entity.User;
import com.justpickup.userservice.domain.user.exception.NotExistUserException;
import com.justpickup.userservice.domain.user.repository.CustomerRepository;
import lombok.*;
import com.justpickup.userservice.domain.user.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.env.Environment;
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.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.core.env.Environment;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
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.io.Serializable;
import java.util.Collections;
import javax.servlet.http.HttpServletResponse;
import java.io.Serializable;
import java.util.Collections;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
@Transactional(readOnly = true,propagation = Propagation.SUPPORTS)
@Slf4j
public class UserServiceImpl implements UserService, UserDetailsService {
private final CustomerRepository customerRepository;
private final UserRepository userRepository;
private final PasswordEncoder passwordEncoder;
private final HttpServletResponse response;
private final Environment env;
private final HttpServletRequest request;
private final JwtTokenProvider jwtTokenProvider;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
@@ -85,31 +79,11 @@ public class UserServiceImpl implements UserService, UserDetailsService {
return userRepository.save(storeOwner);
}
@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public static class AuthResponse{
private String id;
private String name;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
static class AuthRequest {
private String code;
private String client_id;
private String client_secret;
}
@Override
@Transactional(readOnly = false)
@Transactional
public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
OAuth2UserService<OAuth2UserRequest,OAuth2User> delegate = new DefaultOAuth2UserService();
OAuth2User oAuth2User = delegate.loadUser(userRequest);
@@ -124,28 +98,53 @@ public class UserServiceImpl implements UserService, UserDetailsService {
// OAuth2UserService
OAuthAttributeDto attributeDto = OAuthAttributeDto.of(registrationId, userNameAttributeName,oAuth2User.getAttributes());
Customer customer = customerRepository.save(
customerRepository.findByEmail(attributeDto.getEmail())
.orElse(attributeDto.toEntity(attributeDto))
);
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(
Collections.singleton(new SimpleGrantedAuthority(customer.getRole().getKey()))
authorities
, attributeDto.getAttributes()
, attributeDto.getNameAttributeKey());
}
@Getter
public static class UserPayload implements Serializable {
private String name;
private String email;
public UserPayload(Customer user){
this.name = user.getName();
this.email = user.getEmail();
}
@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

@@ -57,6 +57,8 @@ public class JwtTokenProvider {
.compact();
}
public String getUserId(String token) {
return getClaimsFromJwtToken(token).getSubject();
}