[Spring]Admin과 User entity 및 인증로직 분리

조성현·2023년 2월 16일
0

[1] [2] [3] [4] [5] [6]

@RequiredArgsConstructor
public class UserAuthFilter extends OncePerRequestFilter {

  private final JwtUtil jwtUtil;

  @Override
  protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
      FilterChain filterChain) throws ServletException, IOException {
    try {
      String accessToken = jwtUtil.resolveAccessToken(request);
      if (accessToken != null) {
        // accessToken에서 필요한 값(loginId, Role)과 토큰의 상태를 꺼냄
        TokenInfo accessTokenInfo = jwtUtil.getInfoFromTokenIfValidOrExpired(accessToken);
        if (accessTokenInfo.getJwtStatus() == JwtStatus.EXPIRED) {
          String refreshToken = JwtUtil.resolveRefreshToken(request);
          jwtUtil.checkBlackList(refreshToken);
          jwtUtil.validateToken(refreshToken);
          if (!request.getRequestURI().equals("/api/logout")
              || !request.getRequestURI().equals("/api/withdrawal")) {
            accessToken = jwtUtil.createAccessToken(accessTokenInfo.getLoginId(),
                accessTokenInfo.getUserRole());
            response.addHeader(JwtUtil.AUTHORIZATION_HEADER, accessToken);
            response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
            return;
          }
        }
        Authentication authentication = jwtUtil.createAuthentication(accessTokenInfo.getLoginId(),
            "userDetailsServiceImpl");
        SecurityContextHolder.getContext().setAuthentication(authentication);
      }
    } catch (Exception e) {
      response.sendError(HttpServletResponse.SC_UNAUTHORIZED, e.getMessage());
      return;
    }
    filterChain.doFilter(request, response);
  }

}
@RequiredArgsConstructor
public class JwtAuthFilter extends OncePerRequestFilter {
  private final JwtUtil jwtUtil;
  @Override
  protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
      FilterChain filterChain) throws ServletException, IOException {
    try {
      String accessToken = jwtUtil.resolveAccessToken(request);
      String adminToken = jwtUtil.resolveAdminToken(request);
      if (adminToken != null) {
        accessToken = adminToken;
      }
      if (accessToken != null) {
        // accessToken에서 필요한 값(loginId, Role)과 토큰의 상태를 꺼냄
        TokenInfo accessTokenInfo = jwtUtil.getInfoFromToken(accessToken);
        TokenInfo accessTokenInfo = jwtUtil.getInfoFromTokenIfValidOrExpired(accessToken);
        if (accessTokenInfo.getJwtStatus() == JwtStatus.EXPIRED) {
          String refreshToken = JwtUtil.resolveRefreshToken(request);
          jwtUtil.checkBlackList(refreshToken);
          jwtUtil.validateToken(refreshToken);
          if (!request.getRequestURI().equals("/api/logout")) {
            accessToken = jwtUtil.createAccessToken(accessTokenInfo.getLoginId(),
                accessTokenInfo.getUserRole());
            response.addHeader(JwtUtil.AUTHORIZATION_HEADER, accessToken);
            response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
            return;
          }
        }
        Authentication authentication = jwtUtil.createAuthentication(accessTokenInfo.getLoginId());
        SecurityContextHolder.getContext().setAuthentication(authentication);
      }
    } catch (Exception e) {
      response.sendError(HttpServletResponse.SC_UNAUTHORIZED, e.getMessage());
      return;
    }
    filterChain.doFilter(request, response);
  }
}
public class UserDetailsServiceImpl implements UserDetailsService {

  private final UserRepository userRepository;
  private final AdminRepository adminRepository;

  @Override
  public UserDetails loadUserByUsername(String loginId) throws UsernameNotFoundException {
    
    try {
      User user = userRepository.findByLoginId(loginId)
          .orElseThrow(() -> new UsernameNotFoundException("사용자를 찾을 수 없습니다."));
      return new UserDetailsImpl(user, loginId, user.getId());
    } catch (Exception e) {
      Admin admin = adminRepository.findByLoginId(loginId)
          .orElseThrow(() -> new UsernameNotFoundException("관리자를 찾을 수 없습니다."));
      return new AdminDetails(admin, loginId, admin.getId());
    }
  }
}

팩토리패턴

@Service
@RequiredArgsConstructor
public class ServiceFactory {
    private final Map<String, UserDetailsService> userDetailsServiceMap;

    public UserDetailsService getService(ServiceType serviceType){
        if (serviceType == ServiceType.USER){
            return userDetailsServiceMap.get("userDetailsServiceImpl");
        }
        return userDetailsServiceMap.get("adminDetailsService");
    }

}
public enum ServiceType {
    USER, ADMIN
}
@Slf4j
@Component
@RequiredArgsConstructor
public class JwtUtil {
/// 중간 생략
public Authentication createAuthentication(String loginId, ServiceType serviceType) {
    UserDetails userDetails = serviceFactory.getService(serviceType).loadUserByUsername(loginId);
    return new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
  }
@RequiredArgsConstructor
public class AdminAuthFilter extends OncePerRequestFilter {

  private final JwtUtil jwtUtil;

  @Override
  protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
      FilterChain filterChain) throws ServletException, IOException {
    try {
      String adminToken = jwtUtil.resolveAdminToken(request);
      if (adminToken != null) {
        String loginId = jwtUtil.getLoginIdFromTokenIfValid(adminToken);
        ///핵심 (아래)
        Authentication authentication = jwtUtil.createAuthentication(loginId, ServiceType.ADMIN);
       ///핵심 (위)
       SecurityContextHolder.getContext().setAuthentication(authentication);
      }
    } catch (Exception e) {
      response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
      return;
    }
    filterChain.doFilter(request, response);
  }
}
profile
맛있는 음식과 여행을 좋아하는 당당한 뚱땡이

0개의 댓글