JiwonDev

Spring Security๋ž€ ๋ฌด์—‡์ผ๊นŒ

by JiwonDev

# ์ธ์ฆ๊ณผ ์ธ๊ฐ€

  • ์ธ์ฆ(Authentication) ์€ ๋‚ด๊ฐ€ ๋ˆ„๊ตฌ์ธ์ง€ ์‹๋ณ„ํ•˜๊ณ , ์ž…์ฆํ•˜๋Š” ๊ณผ์ •์ด๋‹ค.
  • ์ธ๊ฐ€(Authorization) ์€ ์ธ์ฆ์ด ์™„๋ฃŒ๋œ ์‚ฌ์šฉ์ž์˜ ๊ถŒํ•œ์„ ์„ค์ •ํ•˜๋Š” ๊ณผ์ •์ด๋‹ค.
  • ์ ‘๊ทผ ์ฃผ์ฒด(Principal) ์€ ๋ณดํ˜ธ๋œ ๋Œ€์ƒ์— ์ ‘๊ทผํ•˜๋Š” ์œ ์ € ๋˜๋Š” ์‹œ์Šคํ…œ์„ ์˜๋ฏธํ•œ๋‹ค.
  • ์—ญํ• (Role) ์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•ด์•ผํ•œ๋‹ค.

 

 

# ์„œ๋ธ”๋ฆฟ๊ณผ ํ•„ํ„ฐ

์ธ์ฆ, ์ธ๊ฐ€๋ฅผ ๋‹ด๋‹นํ•˜๋Š” ์ฝ”๋“œ๋„ ๊ธฐ์กด์˜ ์„œ๋น„์Šค์™€ ํ•จ๊ป˜ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค. ์‹ค์ œ๋กœ ์„œ๋ธ”๋ฆฟ ์ดˆ๊ธฐ์—๋„ ๊ทธ๋žฌ์—ˆ๋‹ค.

ํ•˜์ง€๋งŒ [๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง]๊ณผ [์ธ์ฆ, ์ธ๊ฐ€๋ฅผ ๋‹ด๋‹นํ•˜๋Š” ๋กœ์ง]์€ ์„œ๋กœ์˜ ์—ญํ• ์ด ๋‹ค๋ฅด๊ณ  ์ „ํ˜€ ๊ด€๋ จ์ด ์—†๋‹ค. ๋ชจ๋“  ๊ฐ์ฒด์— ๊ฐ™์€ ๋ณด์•ˆ์„ ์ ์šฉํ•  ๊ฒฝ์šฐ ์ฝ”๋“œ๋Š” ๋ฐ˜๋ณต๋˜๊ณ  ์ˆ˜์ •ํ–ˆ์„ ๋•Œ ์•„๋ฌด๋Ÿฐ ์ƒ๊ด€์—†๋Š” ์˜์—ญ๊นŒ์ง€ ๋ณ€๊ฒฝ์ด ์ „ํŒŒ๋˜๋Š” ์ƒ๋‹นํžˆ ํฐ ๋‹จ์ ์ด ์žˆ๋‹ค.

 

๊ทธ๋ž˜์„œ ์„œ๋ธ”๋ฆฟ 2.3๋ถ€ํ„ฐ ํ•„ํ„ฐ๋ผ๋Š” ๊ฐœ๋…์„ ๋„์ž…ํ–ˆ๊ณ , ํ•„ํ„ฐ๋Š” ์„œ๋ธ”๋ฆฟ๊ณผ ์œ ์‚ฌํ•˜๋‚˜ Request, Response๋ฅผ ๋จผ์ € ๋ฐ›์•„ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค. ์š”์ฒญ์ด ๋‹ด๋‹น ์„œ๋ธ”๋ฆฟ์— ๋„๋‹ฌํ•˜๊ธฐ ์ „ ํ•„ํ„ฐ ์ฒด์ธ์„ ๊ฑฐ์น˜๋„๋ก ํ•ด์„œ ์ด๋ฅผ ํ•ด๊ฒฐํ–ˆ์—ˆ๋‹ค.

๊ธฐ์กด์˜ ์ธ์ฆ, ์ธ๊ฐ€๋‚˜ ๋ณด์•ˆ์— ๊ด€๋ จ๋œ ๋ถ€๋ถ„์€ ์ด ํ•„ํ„ฐ๋ฅผ ์ด์šฉํ•˜์—ฌ ๊ตฌํ˜„ํ•˜๋Š”๊ฒŒ ์ผ๋ฐ˜์ ์ด์—ˆ๋‹ค. ์šฐ๋ฆฌ๊ฐ€ ํ”ํžˆ ์•Œ๊ณ  ์žˆ๋Š” ๋กœ๊ทธ์ธ/๋กœ๊ทธ์•„์›ƒ์„ ์˜ˆ์‹œ๋กœ ๋“ค๋ฉด ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

1. ์‚ฌ์šฉ์ž๋Š” ๋กœ๊ทธ์ธ์„ ํ•œ๋‹ค.

2. ์‹œ์Šคํ…œ์€ ๋กœ๊ทธ์ธํ•œ ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ์„ธ์…˜์— ์ €์žฅํ•œ๋‹ค. 

3. ์‚ฌ์šฉ์ž๋Š” ๊ธฐ๋Šฅ์„ ์š”์ฒญํ•œ๋‹ค.

4. ์‹œ์Šคํ…œ์€ ์‚ฌ์šฉ์ž๊ฐ€ ์š”์ฒญํ•œ ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์ „์— ์š”์ฒญํ•œ ์‚ฌ์šฉ์ž์˜ ์„ธ์…˜์„ ์ฒดํฌํ•œ๋‹ค.

5. ์‹œ์Šคํ…œ์€ ์˜ฌ๋ฐ”๋ฅธ ์„ธ์…˜์ผ ๊ฒฝ์šฐ ๊ธฐ๋Šฅ ์Šน์ธ, ์„ธ์…˜์ด ์—†๊ฑฐ๋‚˜ ๊ถŒํ•œ์ด ์—†๋Š” ์‚ฌ์šฉ์ž์ธ ๊ฒฝ์šฐ ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€๋กœ ์ด๋™.

@WebServlet(name = "loadAppConfig", urlPatterns = { "/loadConfig" }, loadOnStartup = 1)
public class LoggingFilter implements Filter {
 
    // ํ•„ํ„ฐ ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋  ๋•Œ ์ดˆ๊ธฐํ™”์‹œ ์‚ฌ์šฉ
    // config ๊ฐ์ฒด์—์„œ ํ•„ํ„ฐ ์ •๋ณด, ์ฃผ์–ด์ง„ ํŒŒ๋ผ๋ฉ”ํƒ€, ์„œ๋ธ”๋ฆฟ ์ •๋ณด๋“ฑ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค.
    public void init(FilterConfig config) throws ServletException {
        System.out.println("ํ•„ํ„ฐ ์ดˆ๊ธฐํ™” ๋จ");
    }
    
    //์š”์ฒญ์‹œ๋งˆ๋‹ค ํ•„ํ„ฐ๊ฐ€ ์‹คํ–‰ํ•  ๋ฉ”์„œ๋“œ
    public void doFilter(ServletRequest request, ServletResponse  response, FilterChain chain)
            throws IOException, ServletException {
            
        boolean flag = false;

        if (request instanceof HttpServletRequest) {
            HttpServletRequest req = (HttpServletRequest) request;

            //์„ธ์…˜ ๋ฐ›์•„์˜ด
            HttpSession session = req.getSession();

            if (session != null) {
                if (session.getAttribute("customInfo") != null) { flag = true;}
            }

            if (flag) {
                //๋กœ๊ทธ์ธ์„ ํ–ˆ์„๊ฒฝ์šฐ ๋‹ค์Œ ํ•„ํ„ฐ ์ฒด์ธ์œผ๋กœ ์ด๋™
                chain.doFilter(request, response);

            } else {
                //๋กœ๊ทธ์ธ ํ•˜์ง€ ์•Š์•˜์œผ๋ฏ€๋กœ ๋กœ๊ทธ์ธํŽ˜์ด์ง€๋กœ ํฌ์›Œ๋“œ
                RequestDispatcher rd = request.getRequestDispatcher("/member/login.jsp");
                rd.forward(request, response);
            }
    }
 
    //ํ•„ํ„ฐ ๊ฐ์ฒด๊ฐ€ ์ œ๊ฑฐ๋  ๋•Œ ์‹คํ–‰
    public void destroy() {
        System.out.println("ํ•„ํ„ฐ ์ œ๊ฑฐ๋จ.");
    }
}

 

 

# ์Šคํ”„๋ง์—์„œ์˜ ํ•„ํ„ฐ

์Šคํ”„๋ง MVC๋Š” ๋งˆ๋ฒ•์˜ ๋„๊ตฌ๊ฐ€ ์•„๋‹ˆ๋‹ค. ์ถ”์ƒํ™” ๋˜์—ˆ์„ ๋ฟ ์ž๋ฐ”์™€ ์„œ๋ธ”๋ฆฟ์œผ๋กœ ํ†ฐ์บฃ ๊ฐ™์€ WAS์—์„œ ๋™์ž‘ํ•˜๋Š”๊ฑด ๋™์ผํ•˜๋‹ค.

์Šคํ”„๋ง MVC๋Š” ํ”„๋ก ํŠธ ์ปจํŠธ๋กค๋Ÿฌ ํŒจํ„ด์„ ์ด์šฉํ•œ๋‹ค. ์ฆ‰ ๋‹จ ํ•˜๋‚˜์˜ Dispatcher Servlet์„ ์ด์šฉํ•˜์—ฌ ์š”์ฒญ์„ ๋ฐ›๊ณ  ์„œ๋น„์Šค๋ฅผ ์ถ”์ƒํ™” ํ•œ๋‹ค.

 

์ฆ‰ ์Šคํ”„๋ง์—์„œ๋„ ํ•„ํ„ฐ๋ฅผ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ์Šคํ”„๋ง ๋ถ€ํŠธ๋ฅผ ์ด์šฉํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ๊ฐ„๋‹จํ•˜๊ฒŒ ๋“ฑ๋กํ•  ์ˆ˜ ์žˆ๋‹ค.

// ํ•„ํ„ฐ๋ฅผ ์ปดํฌ๋„ŒํŠธ ์ž๋™์Šค์บ”์œผ๋กœ ๋“ฑ๋ก ํ•˜๋Š” ๋ฐฉ๋ฒ•
@ServletComponentScan
@WebServlet(name = "loadAppConfig", urlPatterns = { "/*" }, loadOnStartup = 1)
public Class LogFilter{ ... }
// FilterRegistrationBean ๋ฅผ ์ด์šฉํ•ด์„œ ์ˆ˜๋™์œผ๋กœ ๋“ฑ๋กํ•˜๋Š” ๋ฐฉ๋ฒ•
// ๋ฌผ๋ก  ํ•„ํ„ฐ ๊ฐ์ฒด๋ฅผ ๊ทธ๋Œ€๋กœ ๋“ฑ๋กํ•ด๋„ ์ƒ๊ด€์—†์ง€๋งŒ, ์‚ฌ์šฉํ•˜๋ฉด ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
import org.springframework.boot.web.servlet.FilterRegistrationBean;
 
@Configuration
public class WebConfig {
  @Bean
  public FilterRegistrationBean logFilter() {
    FilterRegistrationBean<Filter> filterRegistrationBean = new FilterRegistrationBean<>();
    
    filterRegistrationBean.setFilter(new LogFilter());
    filterRegistrationBean.setOrder(1); // ํ•„ํ„ฐ์—์„œ๋Š” ์•ˆ๋˜๋Š” ์ฒด์ธ ์ˆœ์„œ ์ง€์ •๋„ ๊ฐ€๋Šฅ
    filterRegistrationBean.addUrlPatterns("/*"); // ํ•„ํ„ฐ๋ฅผ ์ ์šฉํ•  URL ๊ทœ์น™ ์ถ”๊ฐ€
    return filterRegistrationBean;
  }
}

 

ํ•„ํ„ฐ ๊ฐ์ฒด๋ฅผ ๊ตฌํ˜„ํ•  ๋•Œ์—๋„ ์Šคํ”„๋ง์—์„œ ์ œ๊ณตํ•ด์ฃผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ ์ ˆํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜๋ฉด ํŽธ๋ฆฌํ•˜๋‹ค.

@Slf4j
public class LoginCheckFilter implements Filter {
 
  // ๋กœ๊ทธ์ธ์ด ํ•„์š”์—†๋Š” URL ๋ชจ์Œ (whiteList)
  private static final String[] whitelist = {"/", "/members/add", "/login", "/logout", "/css/*"};
 
  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
      throws IOException, ServletException {
 
    HttpServletRequest httpRequest = (HttpServletRequest) request;
    String requestURI = httpRequest.getRequestURI();
 
    HttpServletResponse httpResponse = (HttpServletResponse) response;
 
    try {
      log.info("์ธ์ฆ ์ฒดํฌ ํ•„ํ„ฐ ์‹œ์ž‘ {}", requestURI);
 
      if (isLoginWhitelistPath(requestURI)) { // ๋กœ๊ทธ์ธ์ด ํ•„์š”ํ•œ ํŽ˜์ด์ง€ ์ ‘์†
        HttpSession session = httpRequest.getSession(false);
        if (session == null || session.getAttribute(SessionConst.LOGIN_MEMBER) == null) {
          // ๋ฏธ์ธ์ฆ ์‚ฌ์šฉ์ž ์š”์ฒญ -> ๋กœ๊ทธ์ธ์œผ๋กœ redirect
          httpResponse.sendRedirect("/login?redirectURL=" + requestURI);
          return;
        }
      }
      
      chain.doFilter(request, response);
    } catch (Exception e) {
      throw e; //์˜ˆ์™ธ์ฒ˜๋ฆฌ & ๋กœ๊น… ๊ฐ€๋Šฅํ•˜์ง€๋งŒ, ํ†ฐ์บฃ๊นŒ์ง€ ์˜ˆ์™ธ๋ฅผ ๋ณด๋‚ด์ฃผ์–ด์•ผ ํ•จ
    } finally {
      log.info("์ธ์ฆ ์ฒดํฌ ํ•„ํ„ฐ ์ข…๋ฃŒ {} ", requestURI);
    }
  }
 
  // ํ™”์ดํŠธ ๋ฆฌ์ŠคํŠธ URL์˜ ๊ฒฝ์šฐ ์ธ์ฆ ์ฒดํฌX
  private boolean isLoginWhitelistPath(String requestURI) {
    // ์Šคํ”„๋ง์˜ PatternMatchUtils๋ฅผ ์‚ฌ์šฉ. ์ด๋ฅผ ์ง์ ‘ ๊ตฌํ˜„ํ•˜๋ฉด ์ฝ”๋“œ๊ฐ€ ๋งค์šฐ ๋ณต์žกํ•ด์ง„๋‹ค.
    return !PatternMatchUtils.simpleMatch(whitelist, requestURI);
  }
}

 

 

# ์Šคํ”„๋ง ์ธํ„ฐ์…‰ํ„ฐ

์„œ๋ธ”๋ฆฟ์€ ์ž๋ฐ” ์›น ํ‘œ์ค€์—์„œ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋Šฅ์ด๋ผ๋ฉด, ์ธํ„ฐ์…‰ํ„ฐ๋Š” ์Šคํ”„๋ง MVC์—์„œ๋งŒ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋Šฅ์ด๋‹ค.
์„œ๋ธ”๋ฆฟ๊ณผ ์ƒ๊ด€์—†์ด Dispatcher Servlet์—์„œ ์ปจํŠธ๋กค๋Ÿฌ์— ๊ฐ€๊ธฐ ์ „์— ์‹คํ–‰๋œ๋‹ค. ์ฆ‰ ์Šคํ”„๋ง MVC์˜ ํ•ต์‹ฌ์ธ Dispatcher Servlet์—์„œ ๋™์ž‘ํ•˜๋Š” ๋ชจ๋“  ๊ฐ์ฒด๋“ค, ์˜ˆ์™ธ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค.

public interface HandlerInterceptor {
    
  // ์ปจํŠธ๋กค๋Ÿฌ ์š”์ฒญ ์ „
  default boolean preHandle(HttpServletRequest request, HttpServletResponse response,
      Object handler) throws Exception {
  }
 
  // ์ปจํŠธ๋กค๋Ÿฌ ํ˜ธ์ถœ ์ดํ›„ (๋ทฐ์— ์ „๋‹ฌํ•  Model ๊ฐ์ฒด ์ œ๊ณต)
  default void postHandle(HttpServletRequest request, HttpServletResponse response,
      Object handler, @Nullable ModelAndView modelAndView)
      throws Exception {
  }
 
  // ์™„์ „ํ•˜๊ฒŒ HTTP ์š”์ฒญ์ด ๋๋‚œ ์ดํ›„ (Exception ์ œ๊ณต)
  default void afterCompletion(HttpServletRequest request, HttpServletResponse response,
      Object handler, @Nullable Exception ex) throws
      Exception {
  }
}

 

 

# ์„œ๋ธ”๋ฆฟ vs ์ธํ„ฐ์…‰ํ„ฐ

์ธํ„ฐ์…‰ํ„ฐ์˜ ๊ธฐ๋Šฅ์ด ๋” ๊ฐ•๋ ฅํ•˜๊ธด ํ•˜์ง€๋งŒ, ์ด๋Š” ์Šคํ”„๋ง์—์„œ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์ด๋‹ค.

์„œ๋ธ”๋ฆฟ๊ณผ ํ•„ํ„ฐ๋Š” J2EE ํ‘œ์ค€ ์ŠคํŽ™์— ์ •์˜ ๋˜์–ด์žˆ๋Š” ๊ธฐ๋Šฅ์ด๊ธฐ์— Web app์— ์ „์—ญ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•ด์•ผํ•˜๋Š” ๊ธฐ๋Šฅ์€ ํ•„ํ„ฐ๋กœ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์ด ์ข‹๊ณ , ํด๋ผ์ด์–ธํŠธ์— ๋“ค์–ด์˜ค๋Š” ๋””ํ…Œ์ผํ•œ ์ฒ˜๋ฆฌ๋Š” ์ธํ„ฐ์…‰ํ„ฐ์˜ ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๋Š”๊ฒŒ ๊น”๋”ํ•˜๋‹ค.

์ฐธ๊ณ ๋กœ ์Šคํ”„๋ง MVC์—์„œ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ํ๋ฆ„์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

HandlerExceptionResolver๋Š” ์ปจํŠธ๋กค๋Ÿฌ์—์„œ ๋ฐœ์ƒํ•œ ์—๋Ÿฌ๋ฅผ WAS์— ๋„˜๊ธฐ์ง€ ์•Š๊ณ  ์ค‘๊ฐ„์— ๊ฐ€๋กœ์ฑ„์„œ ์ฒ˜๋ฆฌํ•œ๋‹ค. (ํ•ด๋‹น ์—๋Ÿฌ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” Resolver๊ฐ€ ์žˆ๋‹ค๋ฉด)

 

 


# ์Šคํ”„๋ง์—์„œ ํ•„ํ„ฐ๋Š” ์–ด๋–ป๊ฒŒ ์ถ”๊ฐ€๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋Š”๊ฑฐ์ฃ ?

์Šคํ”„๋ง์—์„œ๋Š” ์„œ๋ธ”๋ฆฟ ์š”์ฒญ์ด ๋“ค์–ด์˜ค๋ฉด ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ(ApplicationContext)์™€ ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š” DelegationFilterProxy๋ผ๋Š” ์„œ๋ธ”๋ฆฟ ํ•„ํ„ฐ๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

 

DelegationFilterProxy๋ฅผ ํ†ตํ•ด ์Šคํ”„๋ง ๋นˆ์œผ๋กœ ๊ตฌํ˜„ํ•œ ํ•„ํ„ฐ๋ฅผ ๋“ฑ๋กํ•˜๊ณ , ์„œ๋ธ”๋ฆฟ ํ‘œ์ค€ ํ•„ํ„ฐ์ฒ˜๋Ÿผ ๋™์ž‘ํ•˜๊ฒŒ ๋œ๋‹ค. 

์ฆ‰, Spring Security๊ฐ€ Filter๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๊ตฌํ˜„ํ–ˆ๋‹ค๋Š” ๋ง์€, DelegationFilterProxy๋ฅผ ํ†ตํ•ด ํ•„ํ„ฐ๋ฅผ ๋“ฑ๋กํ–ˆ๋‹ค๋Š” ๋ง์ด๋‹ค.

Spring Security๋Š” FilterChainProxy๋ฅผ ํ†ตํ•ด ๋‹ค์–‘ํ•œ ํ•„ํ„ฐ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๋ฉฐ, ์ด๋Š” ์Šคํ”„๋ง ๋นˆ์ด๊ธฐ์— DelegationFilterProxy๋ฅผ ํ†ตํ•ด ํ•„ํ„ฐ์— ์ถ”๊ฐ€๋œ๋‹ค.

FilterChainProxy๋Š” Spring Security์—์„œ ์ œ๊ณตํ•˜๋Š” ํŠน์ˆ˜ ํ•„ํ„ฐ๋กœ ๋‹ค์–‘ํ•œ ์ธ์Šคํ„ด์Šค๋ฅผ SecurityFilterChain์„ ํ†ตํ•ด ์œ„์ž„์„ ํ•˜๊ณ  ์žˆ๋‹ค. ์ผ์ข…์˜ ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ๋ฅผ ์œ„ํ•œ ๋””์ŠคํŒจ์ณ ์„œ๋ธ”๋ฆฟ์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋œ๋‹ค.

https://bloowhale.tistory.com/13

 

Spring Security ๊ตฌ์กฐ์™€ ์ธ์ฆ ๋ฐฉ์‹์˜ ์ดํ•ด - 01

01. Spring Security ๊ตฌ์กฐ ์†Œ๊ฐœ Filter of Spring Security Filter ๋ž€ ๋ฌด์—‡์ด๊ณ  ์–ด๋–ค ์—ญํ• ์„ ํ•˜๋Š”๊ฐ€? Filter๋ž€ ์ง์—ญ์„ ํ•˜์ž๋ฉด ์—ฌ๊ณผ๊ธฐ ๋ฅผ ๋œปํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด ์ž๋ฐ”์—์„œ์˜ Filter, Spring Security ์—์„œ์˜ ํ•„ํ„ฐ๋Š” ๋ฌด..

bloowhale.tistory.com

 


# Spring Security๋ž€?

์Šคํ”„๋ง ์žฌ๋‹จ์—์„œ ์ œ๊ณตํ•˜๋Š” ๋ชจ๋“ˆ ์ค‘ ํ•˜๋‚˜์ด๋ฉฐ, ์Šคํ”„๋ง์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๋Š” ๋ณด์•ˆ ํ”„๋ ˆ์ž„์›Œํฌ์ด๋‹ค.

Spring Security๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ž์ฒด์ ์œผ๋กœ ์„ธ์…˜์„ ์ฒดํฌํ•˜๊ณ , ๋ฆฌ๋‹ค์ด๋ ‰์…˜ํ•˜๋˜ ๊ฒƒ๋“ค์„ ์ถ”์ƒํ™”ํ•˜์—ฌ ํŽธํ•˜๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

Spring Security๋Š” ์Šคํ”„๋ง ์˜์กด์„ฑ์„ ์—†์• ๊ธฐ ์œ„ํ•ด ํ•„ํ„ฐ(Filter)๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋™์ž‘ํ•œ๋‹ค. ์ฆ‰ ๊ธฐ์กด์˜ Spring MVC, ๋น„์ฆˆ๋‹ˆ์Šค ์ฝ”๋“œ์™€ ์™„๋ฒฝํ•˜๊ฒŒ ๋ถ„๋ฆฌํ•˜์—ฌ ๊ด€๋ฆฌ, ๋™์ž‘ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

Spring Seucirty ์—์„œ๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์ ‘ ๋งŒ๋“ค์–ด์•ผํ•  ํ•„ํ„ฐ๋“ค์„ ๊ธฐ๋ณธ์œผ๋กœ ์ œ๊ณตํ•œ๋‹ค.

์ด๋ ‡๊ฒŒ ์ œ๊ณตํ•˜๋Š” 10๊ฐœ ์ด์ƒ์˜ ํ•„ํ„ฐ๋“ค์„ Security Filter Chain์ด๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค.

๊ฐ ํ•„ํ„ฐ๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” ๊ฐ์ฒด๋“ค (Repository, Handle, Manager)

 ๊ฐ ํ•„ํ„ฐ์— ๋Œ€ํ•ด ๊ฐ„๋‹จํ•˜๊ฒŒ ์„ค๋ช…ํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

  • SecurityContextPersistenceFilter : SecurityContextRepository์—์„œ SecurityContext๋ฅผ ๊ฐ€์ ธ์˜ค๊ฑฐ๋‚˜ ์ €์žฅํ•œ๋‹ค.
  • LogoutFilter : ์„ค์ •๋œ ๋กœ๊ทธ์•„์›ƒ URL๋กœ ์˜ค๋Š” ์š”์ฒญ์„ ๊ฐ์‹œํ•˜๋ฉฐ, ํ•ด๋‹น ์œ ์ €๋ฅผ ๋กœ๊ทธ์•„์›ƒ ์ฒ˜๋ฆฌํ•œ๋‹ค.
  • (UsernamePassword)AuthentocationFilter
    (์•„์ด๋””์™€ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” form ๊ธฐ๋ฐ˜ ์ธ์ฆ) ์„ค์ •๋œ ๋กœ๊ทธ์ธ URL๋กœ ์˜ค๋Š” ์š”์ฒญ์„ ๊ฐ์‹œํ•˜๋ฉฐ, ์œ ์ € ์ธ์ฆ์„ ์ฒ˜๋ฆฌ.
    1. AuthenticationManager๋ฅผ ํ†ตํ•œ ์ธ์ฆ ์‹คํ–‰.
    2. ์ธ์ฆ ์„ฑ๊ณต ์‹œ, ์–ป์€ Authentication ๊ฐ์ฒด๋ฅผ SecurityContext์— ์ €์žฅ ํ›„, AuthenticationSuccessHandler ์‹คํ–‰.
    3. ์ธ์ฆ ์‹คํŒจ ์‹œ, AuthenticationFailureHandler ์‹คํ–‰.

  • DefaultLoginPageGeneratingFilter : ์ธ์ฆ์„ ์œ„ํ•œ ๋กœ๊ทธ์ธ ํผ URL์„ ๊ฐ์‹œ.
  • BasicAuthentocationFilter : HTTP ๊ธฐ๋ณธ ์ธ์ฆ ํ—ค๋”๋ฅผ ๊ฐ์‹œํ•˜์—ฌ ์ฒ˜๋ฆฌ.
  • RequestCacheAwareFilter : ๋กœ๊ทธ์ธ ์„ฑ๊ณต ํ›„ , ์›๋ž˜ ์š”์ฒญ ์ •๋ณด๋ฅผ ์žฌ๊ตฌ์„ฑํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ.
  • SecurityContextHolderAwareRequestFilter :
    HttpServletRequestWrapper๋ฅผ ์ƒ์†ํ•œ SecurityContextHolderAwareRequestWrapper ํด๋ž˜์Šค๋กœ HttpServletRequest ์ •๋ณด๋ฅผ ๊ฐ์‹ผ๋‹ค. SecurityContextHolderAwareRequestWrapper๋Š” ํ•„ํ„ฐ ์ฒด์ธ์ƒ์˜ ๋‹ค์Œ ํ•„ํ„ฐ๋“ค์—๊ฒŒ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•œ๋‹ค

  • AnonymousAuthenticationFilter : ์ด ํ•„ํ„ฐ๊ฐ€ ํ˜ธ์ถœ๋˜๋Š” ์‹œ์ ๊นŒ์ง€ ์‚ฌ์šฉ์ž ์ •๋ณด๊ฐ€ ์ธ์ฆ๋˜์ง€ ์•Š์•˜๋‹ค๋ฉด, ์ธ์ฆ ํ† ํฐ์— ์‚ฌ์šฉ์ž๊ฐ€ ์ต๋ช… ์‚ฌ์šฉ์ž๋กœ ๋‚˜ํƒ€๋‚œ๋‹ค.
  • SessionManagementFilter : ์ด ํ•„ํ„ฐ๋Š” ์ธ์ฆ๋œ ์‚ฌ์šฉ์ž์™€ ๊ด€๋ ค๋œ ๋ชจ๋“  ์„ธ์…˜์„ ์ถ”์ ํ•œ๋‹ค.
  • ExceptionTranslationFilter : ์ด ํ•„ํ„ฐ๋Š” ๋ณดํ˜ธ๋œ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ์ค‘์— ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์˜ˆ์™ธ๋ฅผ ์œ„์ž„, ์ „๋‹ฌํ•œ๋‹ค.
  • FilterSecurityINterceptor : AccessDecisionManager๋กœ์จ ๊ถŒํ•œ ๋ถ€์—ฌ์ฒ˜๋ฆฌ๋ฅผ ์œ„์ž„ํ•˜์—ฌ ์ ‘๊ทผ ์ œ์–ด๋ฅผ ์‰ฝ๊ฒŒ ํ•ด์ค€๋‹ค.

๋ธ”๋กœ๊ทธ์˜ ์ •๋ณด

JiwonDev

JiwonDev

ํ™œ๋™ํ•˜๊ธฐ