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:
@@ -0,0 +1,73 @@
|
|||||||
|
package com.justpickup.customerapigatewayservice.filter;
|
||||||
|
|
||||||
|
import com.justpickup.customerapigatewayservice.security.JwtTokenProvider;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.cloud.gateway.filter.GatewayFilter;
|
||||||
|
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||||
|
import org.springframework.http.server.reactive.ServerHttpResponse;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.server.ServerWebExchange;
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Slf4j
|
||||||
|
public class AuthorizationHeaderFilter extends AbstractGatewayFilterFactory<AuthorizationHeaderFilter.Config> {
|
||||||
|
|
||||||
|
private final JwtTokenProvider jwtTokenProvider;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public AuthorizationHeaderFilter(JwtTokenProvider jwtTokenProvider) {
|
||||||
|
super(Config.class);
|
||||||
|
this.jwtTokenProvider = jwtTokenProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Config {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GatewayFilter apply(Config config) {
|
||||||
|
return (exchange, chain) -> {
|
||||||
|
ServerHttpRequest request = exchange.getRequest();
|
||||||
|
|
||||||
|
HttpHeaders headers = request.getHeaders();
|
||||||
|
if (!headers.containsKey(HttpHeaders.AUTHORIZATION)) {
|
||||||
|
return onError(exchange, "No authorization header", HttpStatus.UNAUTHORIZED);
|
||||||
|
}
|
||||||
|
|
||||||
|
String authorizationHeader = headers.get(HttpHeaders.AUTHORIZATION).get(0);
|
||||||
|
|
||||||
|
// JWT 토큰 판별
|
||||||
|
String token = authorizationHeader.replace("Bearer", "");
|
||||||
|
|
||||||
|
if (!jwtTokenProvider.validateJwtToken(token)) {
|
||||||
|
return onError(exchange, "JWT token is not valid", HttpStatus.UNAUTHORIZED);
|
||||||
|
}
|
||||||
|
|
||||||
|
String subject = jwtTokenProvider.getUserId(token);
|
||||||
|
if (false == jwtTokenProvider.getRoles(token).contains("Customer")) {
|
||||||
|
return onError(exchange, "권한 없음", HttpStatus.UNAUTHORIZED);
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerHttpRequest newRequest = request.mutate()
|
||||||
|
.header("user-id", subject)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
return chain.filter(exchange.mutate().request(newRequest).build());
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mono(단일 값), Flux(다중 값) -> Spring WebFlux
|
||||||
|
private Mono<Void> onError(ServerWebExchange exchange, String errorMsg, HttpStatus httpStatus) {
|
||||||
|
log.error(errorMsg);
|
||||||
|
|
||||||
|
ServerHttpResponse response = exchange.getResponse();
|
||||||
|
response.setStatusCode(httpStatus);
|
||||||
|
|
||||||
|
return response.setComplete();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
package com.justpickup.customerapigatewayservice.security;
|
||||||
|
|
||||||
|
import io.jsonwebtoken.*;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Slf4j
|
||||||
|
public class JwtTokenProvider {
|
||||||
|
|
||||||
|
@Value("${token.access-expired-time}")
|
||||||
|
private long ACCESS_EXPIRED_TIME;
|
||||||
|
|
||||||
|
@Value("${token.refresh-expired-time}")
|
||||||
|
private long REFRESH_EXPIRED_TIME;
|
||||||
|
|
||||||
|
@Value("${token.secret}")
|
||||||
|
private String SECRET;
|
||||||
|
|
||||||
|
public String createJwtAccessToken(String userId, String uri, List<String> roles) {
|
||||||
|
Claims claims = Jwts.claims().setSubject(userId);
|
||||||
|
claims.put("roles", roles);
|
||||||
|
|
||||||
|
return Jwts.builder()
|
||||||
|
.addClaims(claims)
|
||||||
|
.setExpiration(
|
||||||
|
new Date(System.currentTimeMillis() + ACCESS_EXPIRED_TIME)
|
||||||
|
)
|
||||||
|
.setIssuedAt(new Date())
|
||||||
|
.signWith(SignatureAlgorithm.HS512, SECRET)
|
||||||
|
.setIssuer(uri)
|
||||||
|
.compact();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String createJwtRefreshToken() {
|
||||||
|
Claims claims = Jwts.claims();
|
||||||
|
claims.put("value", UUID.randomUUID());
|
||||||
|
|
||||||
|
return Jwts.builder()
|
||||||
|
.addClaims(claims)
|
||||||
|
.setExpiration(
|
||||||
|
new Date(System.currentTimeMillis() + REFRESH_EXPIRED_TIME)
|
||||||
|
)
|
||||||
|
.setIssuedAt(new Date())
|
||||||
|
.signWith(SignatureAlgorithm.HS512, SECRET)
|
||||||
|
.compact();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public String getUserId(String token) {
|
||||||
|
return getClaimsFromJwtToken(token).getSubject();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Claims getClaimsFromJwtToken(String token) {
|
||||||
|
try {
|
||||||
|
return Jwts.parser().setSigningKey(SECRET).parseClaimsJws(token).getBody();
|
||||||
|
} catch (ExpiredJwtException e) {
|
||||||
|
return e.getClaims();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRefreshTokenId(String token) {
|
||||||
|
return getClaimsFromJwtToken(token).get("value").toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getRoles(String token) {
|
||||||
|
return (List<String>) getClaimsFromJwtToken(token).get("roles");
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean validateJwtToken(String token) {
|
||||||
|
try {
|
||||||
|
Jwts.parser().setSigningKey(SECRET).parseClaimsJws(token);
|
||||||
|
return true;
|
||||||
|
} catch (SignatureException e) {
|
||||||
|
log.error("Invalid JWT signature: {}", e.getMessage());
|
||||||
|
return false;
|
||||||
|
} catch (MalformedJwtException e) {
|
||||||
|
log.error("Invalid JWT token: {}", e.getMessage());
|
||||||
|
return false;
|
||||||
|
} catch (ExpiredJwtException e) {
|
||||||
|
log.error("JWT token is expired: {}", e.getMessage());
|
||||||
|
return false;
|
||||||
|
} catch (UnsupportedJwtException e) {
|
||||||
|
log.error("JWT token is unsupported: {}", e.getMessage());
|
||||||
|
return false;
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
log.error("JWT claims string is empty: {}", e.getMessage());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equalRefreshTokenId(String refreshTokenId, String refreshToken) {
|
||||||
|
String compareToken = this.getRefreshTokenId(refreshToken);
|
||||||
|
return refreshTokenId.equals(compareToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -37,6 +37,47 @@ spring:
|
|||||||
- id: user-service
|
- id: user-service
|
||||||
uri: lb://USER-SERVICE
|
uri: lb://USER-SERVICE
|
||||||
predicates:
|
predicates:
|
||||||
- Path=/user-service/**
|
- Path=/user-service/login
|
||||||
|
- Method=POST
|
||||||
filters:
|
filters:
|
||||||
- RewritePath=/user-service/(?<segment>.*),/$\{segment}
|
- RewritePath=/user-service/(?<segment>.*),/$\{segment}
|
||||||
|
- id: user-service
|
||||||
|
uri: lb://USER-SERVICE
|
||||||
|
predicates:
|
||||||
|
- Path=/user-service/refreshToken
|
||||||
|
- Method=GET
|
||||||
|
filters:
|
||||||
|
- RewritePath=/user-service/(?<segment>.*),/$\{segment}
|
||||||
|
- id: user-service
|
||||||
|
uri: lb://USER-SERVICE
|
||||||
|
predicates:
|
||||||
|
- Path=/user-service/logout
|
||||||
|
- Method=POST
|
||||||
|
filters:
|
||||||
|
- RewritePath=/user-service/(?<segment>.*),/$\{segment}
|
||||||
|
- id: user-service
|
||||||
|
uri: lb://USER-SERVICE
|
||||||
|
predicates:
|
||||||
|
- Path=/user-service/oauth2/authorization/*
|
||||||
|
filters:
|
||||||
|
- RewritePath=/user-service/(?<segment>.*),/$\{segment}
|
||||||
|
- id: user-service
|
||||||
|
uri: lb://USER-SERVICE
|
||||||
|
predicates:
|
||||||
|
- Path=/user-service/*/oauth2/code/*
|
||||||
|
filters:
|
||||||
|
- RewritePath=/user-service/(?<segment>.*),/$\{segment}
|
||||||
|
- id: user-service
|
||||||
|
uri: lb://USER-SERVICE
|
||||||
|
predicates:
|
||||||
|
- Path=/user-service/**
|
||||||
|
filters:
|
||||||
|
- AuthorizationHeaderFilter
|
||||||
|
- RewritePath=/user-service/(?<segment>.*),/$\{segment}
|
||||||
|
|
||||||
|
token:
|
||||||
|
access-expired-time: 3600000
|
||||||
|
refresh-expired-time: 604800000
|
||||||
|
secret: my-secret
|
||||||
|
refresh-token-name: refresh-token
|
||||||
|
access-token-name: access-token
|
||||||
@@ -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))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@ package com.justpickup.userservice.domain.jwt.service;
|
|||||||
import com.justpickup.userservice.domain.user.dto.JwtTokenDto;
|
import com.justpickup.userservice.domain.user.dto.JwtTokenDto;
|
||||||
|
|
||||||
public interface RefreshTokenService {
|
public interface RefreshTokenService {
|
||||||
|
void updateRefreshToken(Long id, String uuid);
|
||||||
JwtTokenDto refreshJwtToken(String accessToken, String refreshToken);
|
JwtTokenDto refreshJwtToken(String accessToken, String refreshToken);
|
||||||
void logoutToken(String accessToken);
|
void logoutToken(String accessToken);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ import org.springframework.security.core.Authentication;
|
|||||||
import org.springframework.security.core.GrantedAuthority;
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
import org.springframework.security.core.userdetails.UserDetails;
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ public class Customer extends User {
|
|||||||
private AuthType oauthType;
|
private AuthType oauthType;
|
||||||
|
|
||||||
public Customer(String email, String password, String name, String phoneNumber, 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.dtype = Customer.class.getSimpleName();
|
||||||
this.oauthType = oauthType;
|
this.oauthType = oauthType;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,9 +26,6 @@ public abstract class User extends BaseEntity {
|
|||||||
|
|
||||||
private String phoneNumber;
|
private String phoneNumber;
|
||||||
|
|
||||||
@Enumerated(EnumType.STRING)
|
|
||||||
private Role role;
|
|
||||||
|
|
||||||
@Column(insertable = false,updatable = false)
|
@Column(insertable = false,updatable = false)
|
||||||
protected String dtype;
|
protected String dtype;
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +1,13 @@
|
|||||||
package com.justpickup.userservice.domain.user.service;
|
package com.justpickup.userservice.domain.user.service;
|
||||||
|
|
||||||
import com.justpickup.userservice.domain.user.dto.CustomerDto;
|
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.dto.StoreOwnerDto;
|
||||||
import com.justpickup.userservice.domain.user.entity.StoreOwner;
|
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);
|
CustomerDto findCustomerByUserId(Long userId);
|
||||||
StoreOwner saveStoreOwner(StoreOwnerDto storeOwnerDto);
|
StoreOwner saveStoreOwner(StoreOwnerDto storeOwnerDto);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
package com.justpickup.userservice.domain.user.service;
|
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.CustomerDto;
|
||||||
import com.justpickup.userservice.domain.user.dto.OAuthAttributeDto;
|
|
||||||
import com.justpickup.userservice.domain.user.dto.StoreOwnerDto;
|
import com.justpickup.userservice.domain.user.dto.StoreOwnerDto;
|
||||||
import com.justpickup.userservice.domain.user.entity.Customer;
|
import com.justpickup.userservice.domain.user.entity.Customer;
|
||||||
import com.justpickup.userservice.domain.user.entity.StoreOwner;
|
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 com.justpickup.userservice.domain.user.repository.UserRepository;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.security.core.GrantedAuthority;
|
|
||||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||||
import org.springframework.security.core.userdetails.UserDetails;
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
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.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Propagation;
|
import org.springframework.transaction.annotation.Propagation;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@@ -44,9 +31,6 @@ public class UserServiceImpl implements UserService, UserDetailsService {
|
|||||||
private final CustomerRepository customerRepository;
|
private final CustomerRepository customerRepository;
|
||||||
private final UserRepository userRepository;
|
private final UserRepository userRepository;
|
||||||
private final PasswordEncoder passwordEncoder;
|
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());
|
String encode = passwordEncoder.encode(storeOwnerDto.getPassword());
|
||||||
|
|
||||||
StoreOwner storeOwner = new StoreOwner(storeOwnerDto.getEmail(), encode, storeOwnerDto.getName(),
|
StoreOwner storeOwner = new StoreOwner(storeOwnerDto.getEmail(), encode, storeOwnerDto.getName(),
|
||||||
storeOwnerDto.getPhoneNumber(), storeOwnerDto.getBusinessNumber(), storeOwnerDto.getRefreshTokenId());
|
storeOwnerDto.getPhoneNumber(), storeOwnerDto.getBusinessNumber());
|
||||||
|
|
||||||
return userRepository.save(storeOwner);
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.justpickup.userservice.global.security;
|
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.domain.jwt.service.RefreshTokenServiceImpl;
|
||||||
import com.justpickup.userservice.global.utils.JwtTokenProvider;
|
import com.justpickup.userservice.global.utils.JwtTokenProvider;
|
||||||
import com.justpickup.userservice.domain.user.service.UserService;
|
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.config.http.SessionCreationPolicy;
|
||||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||||
|
import org.springframework.security.oauth2.client.userinfo.OAuth2UserService;
|
||||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@@ -26,7 +28,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
|||||||
private final RefreshTokenServiceImpl refreshTokenServiceImpl;
|
private final RefreshTokenServiceImpl refreshTokenServiceImpl;
|
||||||
private final CookieProvider cookieProvider;
|
private final CookieProvider cookieProvider;
|
||||||
|
|
||||||
private final UserService userService;
|
private final OAuthService oAuthService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
|
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
|
||||||
@@ -52,7 +54,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
|||||||
http.oauth2Login()
|
http.oauth2Login()
|
||||||
.defaultSuccessUrl("http://just-pickup.com:8000/customer-frontend-service/")
|
.defaultSuccessUrl("http://just-pickup.com:8000/customer-frontend-service/")
|
||||||
.userInfoEndpoint()
|
.userInfoEndpoint()
|
||||||
.userService(userService);
|
.userService(oAuthService);
|
||||||
|
|
||||||
http.addFilter(loginAuthenticationFilter);
|
http.addFilter(loginAuthenticationFilter);
|
||||||
http.addFilterBefore(new HeaderAuthorizationFilter(), UsernamePasswordAuthenticationFilter.class);
|
http.addFilterBefore(new HeaderAuthorizationFilter(), UsernamePasswordAuthenticationFilter.class);
|
||||||
|
|||||||
Reference in New Issue
Block a user