Spring
[Spring Security6] Json Web Token
[Spring Security6] Json Web Token
2023.08.11JsonWebToken(JWT) 는 JSON 객체를 사용해 정보를 안전하게 전송하는 방법을 의미한다. 주로 권한 부여에 사용되고, 기존 JSESSIONID 쿠키와 세션 기반 사용자 인증의 단점을 극복하기 위해 도입됐다. 기존 세션 기반 인증을 사용하는 경우 서버 측에서 사용자에 대한 정보를 세션에 저장한다. 따라서 서버를 여러 개 분산해서 사용하는 경우 확장성에 문제가 발생할 수 있고, 사용자가 많아질 경우 세션 정보 관리의 오버헤드가 커진다. JWT 기반 인증을 사용할 경우 서버는 사용자의 상태를 세션에 저장할 필요가 없다. 클라이언트의 요청마다 토큰이 포함되고, 이 토큰에는 모든 사용자 정보가 들어있다. 서버에서 세션을 저장하지 않기에 서버를 분산해도 세션 관련 문제가 발생하지 않고 서비스 간 상태를..
[Spring Security6] Authorization과 Filter
[Spring Security6] Authorization과 Filter
2023.08.09Authentication 은 사용자가 누구인지 확인하는 과정이다. 로그인 과정에서 아이디와 비밀번호를 통해 사용자를 확인하는 작업은 Authentication 이다. Authorization 은 사용자의 권한을 의미한다. 인증된 사용자가 어떤 리소스에 접근할 수 있는지 결정한다. Roles 는 권한의 집합을 의미한다. 관리자와 사용자가 Roles라면 사용자 관리, 글 열람은 Authorization 이다. 시큐리티는 GrantedAuthroity 인터페이스를 사용해 사용자에게 부여된 권한을 나타낸다. public final class SimpleGrantedAuthority implements GrantedAuthority { private static final long serialVersionUID..
[Spring Security6] CORS, CSRF
[Spring Security6] CORS, CSRF
2023.08.08브라우저는 기본적으로 Same-Origin Policy를 따르기에 브라우저에서 로드된 웹 페이지가 다른 출처의 리소스에 대한 요청을 제한한다. (보안을 위해 사용한다) Cross Origin Resource Sharing (CORS) Same-Origin Policy 제약을 특정 조건 하에 완화시키기 위한 메커니즘으로, 다른 Origin에서 실행 중인 웹 페이지가 특정 리소스에 액세스 할 수 있도록 허용한다. 애플리케이션을 개발하다 보면 외부 출처에서 리소스나 api에 접근해야 하는 경우가 있는데, CORS는 이런 요구사항을 안전하게 만족시키기 위해 도입됐다. 여기서 사용되는 origin은 통신에 사용되는 프로토콜, 도메인, 포트번호를 포함하는 개념으로 세 가지 구성 요소가 동일하다면 두 URL은 같은 ..
[Spring Security6] 사용자 인증
[Spring Security6] 사용자 인증
2023.08.06스프링 시큐리티의 AuthenticationProvider는 사용자가 로그인 할 때 아이디와 비밀번호를 검증하는 역할을 수행한다. 기본적으로 DaoAuthenticationProvider 구현체를 사용해 데이터베이스에서 사용자 정보를 조회한 후 제공된 자격을 검증하는데, 기본 구현체가 요구사항을 충족시키지 못하는 경우 해당 인터페이스를 직접 구현해 맞춤형 검증 로직을 작성할 수 있다. public interface AuthenticationProvider { Authentication authenticate(Authentication authentication) throws AuthenticationException; boolean supports(Class authentication); } authen..
[Spring Security6] Password Encoder
[Spring Security6] Password Encoder
2023.08.05사용자가 아이디와 비밀번호를 입력하면 스프링 시큐리티는 AuthenticationProvider 를 실행해 저장소에서 UserDetails 객체를 가져온다 (loadUserByUsername 메서드를 사용한다) 데이터베이스에 저장된 비밀번호와 사용자가 입력한 비밀번호를 비교하는데... 여기서 PasswordEncoder를 사용하지 않으면 비밀번호를 Plain Text로 다루고 equals 메서드로 두 비밀번호가 일치하는지 확인한다. 비밀번호를 평문 그대로 다루는건 위험하다. 인코딩 인코딩은 특정 데이터를 다른 형태의 정보로 변환하는 작업을 의미하고, 디코딩은 변환한 데이터를 원본 데이터로 변환하는 작업을 의미한다. 대표적인 예시로 아스키코드, Base64 등이 있다. 이미지나 동영상 데이터를 Base64..
[Spring Security6] 주요 구성요소
[Spring Security6] 주요 구성요소
2023.08.04스프링 시큐리티는 SpringBootWebSecurityConfiguration 파일을 제공해 스프링 부트가 자동으로 제공하는 보안 설정을 구성한다. @Configuration(proxyBeanMethods = false) @ConditionalOnDefaultWebSecurity static class SecurityFilterChainConfiguration { @Bean @Order(SecurityProperties.BASIC_AUTH_ORDER) SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception { http.authorizeHttpRequests((requests) -> requests.anyRequ..
[Spring Security6] 내부 흐름
[Spring Security6] 내부 흐름
2023.07.30브라우저는 HTTP 프로토콜을 기반으로 서버에게 요청을 보낸다. 자바로 작성한 애플리케이션은 HTTP 프로토콜을 기반으로 사용자의 요청을 처리하는데... 자바 코드는 HTTP 프로토콜을 이해할 수 없다. 따라서 브라우저와 자바로 작성한 애플리케이션을 이어주는 다리가 필요하다. 스프링은 이 다리로 서블릿을 사용한다. 서블릿은 HTTP 프로토콜을 이해하고 처리할 수 있는 자바 코드로 생각하면 된다. 사용자의 HTTP 요청이 스프링으로 구축된 서버에 도착하면 가장 먼저 웹 애플리케이션 서버인 Tomcat이 요청을 받는다. 이후 Tomcat은 서블릿에게 HTTP 요청을 전달하고 서블릿은 요청을 처리한다. 처리된 요청은 Tomcat에게 전달되고, Tomcat은 사용자에게 HTTP 응답을 제공한다. Tomcat은 ..
[Spring] AOP 주의사항
[Spring] AOP 주의사항
2023.07.29스프링은 프록시로 AOP를 적용한다. 스프링 컨테이너는 실제 객체 대신 프록시를 스프링 빈으로 등록해 실제 객체를 직접 호출하는 문제가 발생하지 않을 것 같지만... 실제 객체 내부에서 메서드 호출 시 프록시를 거치지 않고 대상 객체를 직접 호출하는 문제가 발생할 수 있다. @Slf4j @Component public class CallServiceV0 { public void external() { log.info("call external"); internal(); //내부 메서드 호출(this.internal()) } public void internal() { log.info("call internal"); } } @Slf4j @Aspect public class CallLogAspect { @B..
[Spring] 포인트컷 지시자
[Spring] 포인트컷 지시자
2023.07.28@Pointcut("execution(...)") 지금까지 포인트컷을 작성할 때는 AspectJ가 제공하는 execution 지시자를 사용해서 작성했다. execution 지시자를 가장 많이 사용하긴 하지만.. AspectJ는 다른 지시자도 제공한다. 포인트컷을 작성하는 방식을 살펴보자. execution execution(접근제어자? 반환타입 선언타입?메서드명(파라미터) 예외?) ?가 뒤에 붙어있으면 생략 가능함을 의미한다. 선언타입은 패키지명과 클래스명을 모두 포함하고 * 표현을 사용할 수 있다. pointcut.setExpression("execution(public String start.aop.member.MemberServiceImpl.hello(String))"); pointcut.setEx..
[Spring] AOP 적용
[Spring] AOP 적용
2023.07.27애플리케이션 로직은 핵심 기능과 부가 기능으로 나뉜다. 트랜잭션 관리, 보안, 로깅 등 부가기능은 애플리케이션 전반에 걸쳐 사용되는 횡단 관심사이고, 횡단 관심사를 효과적으로 처리하기 위해 AOP 기술이 도입됐다. AOP는 부가 기능을 핵심 기능에서 분리하고 한 곳에서 통합해서 관리한다. 부가 기능과 부가 기능을 어디에 적용할 지 선택하는 기능을 Aspect 라고 부르고, @Aspect 애너테이션으로 사용한다. AOP는 Aspect Oriented Programming 의 약자로 이름 그대로 애플리케이션을 바라보는 관점을 기능에서 횡단 관심사로 옮겨서 바라보는 패러다임이고, OOP의 부족한 부분을 보조하는 목적으로 도입됐다. AOP의 구현 중 AspectJ 프레임워크가 있다. 스프링도 AspectJ의 문..
[Spring] 빈 후처리기
[Spring] 빈 후처리기
2023.07.26AOP를 적용하기 위해 프록시 기술에 대해 알아봤는데... 프록시 기술을 적용해 기존 코드를 수정하지 않고 부가 기능을 적용할 수는 있었지만 추가로 수행해 줘야 하는 설정이 너무 많고 빈 등록도 @Configuration과 @Bean 애너테이션을 통해 수동으로 해 줘야 하는 문제점이 있었다. 요즘은 빈 등록을 ComponentScan 방식으로 수행하는데... ComponentScan을 사용하면 빈 등록 과정에 개발자가 개입할 공간이 없어 그대로 실제 클래스를 빈으로 등록할 수 밖에 없다. 이런 문제를 처리하기 위해 빈 후처리기가 도입됐다. (BeanPostProcessor) 빈 후처리기는 스프링이 빈으로 등록할 목적으로 생성한 객체를 등록하기 직전에 조작할 때 사용한다. 객체는 빈으로 등록되기 전 빈 후..
[Spring] 프록시 팩토리
[Spring] 프록시 팩토리
2023.07.24JDK 동적 프록시와 CGLIB를 동시에 사용하려면 InvocationHandler와 MethodInterceptor를 각각 중복해서 만들어서 관리해야 되나? 아니면 인터페이스가 있으면 JDK 동적 프록시를, 클래스만 있으면 CGLIB를 쓰는 방법은 없을까? 이런 요소들을 해결하기 위해 프록시 팩토리가 도입됐다. 팩토리 패턴은 디자인 패턴 중 하나로 객체 생성 로직을 서브 클래스에게 위임해 인스턴스의 생성을 호출하는 측과 실제 생성되는 인스턴스 측으로 분리하는 역할을 한다. 팩토리 클래스 : 인스턴스를 생성하는 메서드를 제공해 인스턴스를 반환한다. 동적 프록시 클래스 : 해당 클래스의 인스턴스는 팩토리로부터 생성된다. 프록시 팩토리를 도입해 중복을 줄일 수 있고 다른 동적 프록시 기술에 대한 확장성을 얻..