DelegatingFilterProxy와 FilterChainProxy DelegatingFilterProxy 일반적인 서블릿 필터이며, 서블릿 필터 처리를 스프링에 들어있는 빈으로 위임할 때 사용한다. 타겟 빈 이름을 설정할 수 있다.
스프링 부트 없이 스프링 시큐리티 설정할 때는 AbstractSecurityWebApplicationInitializer를 사용해서 등록해서 사용하며, 스프링 부트를 사용할 때는 자동으로 등록 된다. (SecurityFilterAutoConfiguration)
FilterChainProxy 스프링부트에서 “springSecurityFilterChain” 이라는 이름의 빈으로 등록된다.
스프링 시큐리티 Filter 스프링 시큐리티가 제공하는 필터들은 다음과 같다. 이 모든 필터는 FilterChainProxy가 호출한다.
WebAsyncManagerIntegrationFilter 스프링 MVC의 Async 기능을 사용할 때에도 SecurityContext를 공유하도록 도와주는 필터이다.
다음은 스프링 시큐리티에서 사용하는 주요 개념에 대한 설명이다.
SecurityContextHolder 지정된 SecurityContext를 현재 실행 스레드와 연결한다. 이 클래스는 SecurityContextHolderStrategy 인스턴스에 위임하는 일련의 정적 메서드를 제공한다.
클래스의 목적은 주어진 JVM에 사용해야 하는 전략을 지정하는 편리한 방법을 제공하는 것이다. 기본적으로 ThreadLocal을 사용한다.
SecurityContext 현재 실행 스레드와 관련된 최소 보안 정보를 정의하는 인터페이스이다. 보안 컨텍스트는 SecurityContextHolder에 저장되며, Authentication을 제공한다.
1 2 3 4 public interface SecurityContext extends Serializable { Authentication getAuthentication(); void setAuthentication(Authentication authentication); } AuthenticationManager 스프링 시큐리티에서 인증을 하는 주체이다.
Filter Filter(필터)는 요청과 응답을 거른 뒤 정제하는 역할을 한다. 서블릿 필터는 DispatcherServlet 이전에 실행이 되는데 필터가 동작하도록 지정된 자원의 앞단에서 요청내용을 변경하거나, 여러 가지 체크를 수행할 수 있다. 또한 자원의 처리가 끝난 후 응답 내용에 대해서도 변경하는 처리를 할 수가 있다. 즉 스프링 컨텍스트 외부에 존재하여 스프링과 무관한 자원에 대해 동작한다. 보통 web.xml에 등록하고, 일반적으로 인코딩 변환 처리, XSS 방어 등의 요청에 대한 처리로 사용된다.
필터 흐름 1 HTTP 요청 -> WAS -> 필터 -> 서블릿 -> 컨트롤러 필터 인터페이스 1 2 3 4 5 public interface Filter { public default void init(FilterConfig filterConfig) throws ServletException{} public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException; public default void destroy() {} } 필터 인터페이스를 구현하고 등록하면 서블릿 컨테이너가 필터를 싱글톤 객체로 생성하고, 관리한다.
Dependency Injection Dependency Injection은 말 그대로 의존성 주입을 말한다. 이는 객체 간의 의존성을 외부에서 주입하여 관리하겠다라는 개념이다. 의존성이 높으면 코드의 재사용성이 떨어지고 변경에 유연하지 못하며 테스트 코드를 작성하기 어려워진다.
외부에서 의존을 주입받으면 의존을 내부에서 정의하지 않기 때문에 객체 간의 의존성을 줄여주고 코드의 재사용성도 증가하며 변화에 민감하지 않을 수 있다. 이때 변화에 민감하다는 말은 객체 자신이 아니라 의존하고 있는 다른 객체의 변경으로부터 민감한 정도를 말한다. 의존의 정도가 작을수록 의존 객체의 변경에 크게 영향을 받지 않는다.
Java에서 String을 생성하는 방식 String 클래스의 경우 다른 참조 자료형과 달리 불변의 원칙이 적용되며, 참조 클래스 중 유일하게 + 연산을 수행할 수 있다.
Java에서 String을 생성하는 방식은 두가지가 있다.
생성자를 이용하는 방법 String str = new String(“Hello”); 리터럴을 이용하는 방법 String str = “Hello”; 1 2 3 4 5 6 7 String a = "apple"; String b = new String("apple"); String c = "apple"; String d = new String("apple"); System.
Java에서 String이 불변인 이유 String은 기본 타입(Primitive Type)이 아닌 참조 타입(Reference Type)이다. 즉, String은 클래스이다.
Java에서 String 객체를 리터럴로 선언하면 특별히 스택 메모리에 직접 저장되는 것이 아니라 Heap 영역 중에서 String constant pool이라는 곳에 메모리를 할당받아 거기에 값을 저장한다. 그리고 String 변수는 그 주소 값을 참조하게 된다. 따라서 Java에서 String은 불변성을 띄게 된다.
Java에서 String이 불변인 이유는 다음과 같다.
String pool을 통해 String을 관리함으로써 Java는 Runtime에서 Heap 영역의 많은 메모리를 절약할 수 있다.