Spring
[Spring Security6] 인증 서버 구축
[Spring Security6] 인증 서버 구축
2023.08.15페이스북, 구글, 깃허브 등 대기업들은 자신만의 OAuth2 인증 서버를 가지고 있다. 따라서 사용자의 구글 정보를 활용하는 서드 파티 애플리케이션을 개발할 때는 구글이 제공하는 Auth Server를 사용해 사용자의 정보에 안전하게 접근하거나 사용자를 인증할 수 있다. 만들어진 Auth Server를 사용하는건 쉽지만, 직접 Auth Server를 구축하는건 쉽지 않다. 애플리케이션을 개발할 때 MSA 기반으로 설계한다면 인증 서버를 다른 요소들과 독립적으로 구축해야 한다. Keycloak, Spring Security OAuth, AWS Cognito, Okta 등 여러 가지 기술을 활용해 인증 서버를 구축할 수 있다. 각 기술들은 OAuth2, OpenID Connect 등의 프로토콜을 지원하고, ..
[Spring Security6] OAuth2와 OpenID Connect
[Spring Security6] OAuth2와 OpenID Connect
2023.08.13OAuth는 웹에서의 인증과 권한 부여에 대한 개방 표준이다. (특정 기술에 대한 구현이 아니다) 한 서비스에서 사용자가 다른 서비스의 정보와 기능을 안전하게 활용할 수 있도록 권한을 부여하고 관리하기 위한 매커니즘을 제공한다. 초기의 애플리케이션은 다른 애플리케이션의 정보를 사용할 때 사용자가 해당 애플리케이션의 아이디와 비밀번호를 직접 제공해 로그인하는 방법을 사용했다. 이 방식은 보안에 취약하고 권한의 범위와 기간도 설정할 수 없다는 단점이 있고, 다양한 제3자 인증 방식이 개발됐지만 공통된 표준이 없어 다양한 방식의 인증 시스템을 다뤄야 했다. 이런 문제점을 해결하기 위해 OAuth 표준이 도입됐다. 처음에는 OAuth1이 도입됐고, 구현의 복잡성과 보안 문제가 있어 개선된 버전인 OAuth2가 ..
[Spring Security 6] 메서드 단위 권한 요청
[Spring Security 6] 메서드 단위 권한 요청
2023.08.12스프링 시큐리티는 권한 요청 및 접근 제어를 수행하는 방법으로 크게 두 가지 방법을 제공한다. 1. URL 기반 권한 요청 시큐리티 설정 클래스에서 URL을 기반으로 접근 권한을 제어한다. HttpSecurity 클래스의 authorizeRequests() 메서드를 사용해 구현한다. 2. 메서드 수준에서의 권한 요청 특정 애너테이션을 사용해 권한을 제어한다. 클래스의 메서드 단위로 권한을 제어할 수 있다. URL 기반 접근 제어만 사용하는 경우도 많지만, 보안 요구사항이 복잡한 경우 두 가지 방법을 함께 사용하기도 한다. 요청이 들어오면 URL 기반 접근 제어가 먼저 실행되고, 그 다음에 메서드 기반의 접근 제어가 수행된다. 전반적인 보안은 URL 기반으로, 세부적인 접근 제어는 메서드 수준에서 수행하자..
[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..