첫번째 프로젝트 시작2.2 기본 구성이란?스프링 시큐리티에서 자동으로 구성되는 빈2.3 기본 구성 재정의2.3.1 UserDetailsService 구성 요소 재정의2.3.2 앤드포인트 권한 부여 구성 재정의2.3.4 AuthenticationProvider 구현 재정의요약
[이장의 목표]
- 스프링 시큐리티와 웹 종속성만 있는 프로젝트를 만들어서 추가된 구성이 없으면 어떻게 작동하는지 확인한다. 이를 통해 인증과 권한 부여의 기본 구성에서 무엇을 기대해야 할지 이해할 수 있다.
- 기본 구성을 재정의하고 맞춤형 사용자와 암호를 정의해서 프로젝트에 사용자 관리 기능을 추가한다.
- 애플리케이션이 기본적으로 모든 앤드포인트를 인증하는 것을 확인하고, 이 동작도 맞춤 구성할 수 있다는 것을 배운다.
- 모범 사례를 이해할 수 있도록 동일한 구성에 대해 다른 스타일을 적용해본다.
첫번째 프로젝트 시작
2.2 기본 구성이란?
- 시큐리티 전체 아키텍처에서 인증과 권한 부여를 처리하는 데 참여하는 주 구성 요소에 대해 알아야한다.
- 사전 구성된 요소를 애플리케이션 필요에 맞게 재정의 해야 하기 때문 !

- 먼저 사용자의 요청을 인증 필터가 가로챈다. 그 후 요청을 인증 관리자에게 위임하고 응답을 바탕으로 보안 컨텍스트를 구성한다.
- 인증 관리자는 인증 공급자를 통해 인증을 처리한다.
- 인증 공급자는 인증 논리를 구현한다.
- 인증 공급자는 사용자 관리 책임을 구현하는 사용자 세부 정보 서비스를 인증 논리에 이용하낟.
- 인증 공급자는 암호 관리를 구현하는 암호 인코더를 인증 논리에 이용한다.
- 보안 컨텍스트는 인증 프로세스 후 인증 데이터를 유지한다.
스프링 시큐리티에서 자동으로 구성되는 빈
- 스프링 부트는 기본 HTTP basic 접근 인증을 구성할 때 인증 방식도 선택하며 이는 가장 직관적인 접근 인증 방식이다.
- Basic 인증에서는 HTTP 요청에 Authorization 헤더를 통해 보내기만 하면 된다. 클라이언트는 헤더 값에 접두사 basic을 붙이고 그 뒤에 콜론으로 구분된 사용자 이름과 암호가 포함된 문자열을 Base64로 인코딩하고 붙인다.
- Basic 인증방식은 기밀성이 보장되지 않기 때문에 HTTPS와 사용하는게 아니라면 이용하지 않는다.
- UserDetailService
- 사용자에 관한 세부 정보는 스프링 시큐리티로 UserDetailService 계약을 구현하는 객체가 관리한다
- 지금까지 기본 세팅으로 스프링 부트가 제공하는 기본 구현을 사용했는데, 이 구현은 애플리케이션의 내부 메모리에 기본 자격 증명을 등록하는 일만 하게된다.
- 기본 자격 증명에서 사용하는 사용자 이름은 “user”이고 기본 암호는 UUID 형식이며 암호는 스프링 컨텍스트가 로드될 때 자동으로 생성된다.
- PasswordEncoder
- 암호를 인코딩한다.
- 암호가 기존 인코딩과 일치하는지 확인한다.
- AuthenticationProvider
- AuthenticationProvider는 인증 논리를 정의하고 사용자와 암호의 관리를 위임한다.
- AuthenticationProvider의 기본 구현은 UserDetailService와 PasswordEncoder에 제공된 기본 구현을 이용한다.
2.3 기본 구성 재정의
- 기본 구성 요소를 재정의하는 옵션을 알아야 하는 이유는 이것이 맞춤형 구현을 연결하고 애플리케이션에 맞게 보안을 적용하는 방법이기 때문이다.
- 애플리케이션을 유지 관리하기 편하도록 구성을 작성하는 것도 개발 프로세스에 중요한 부분을 차지한다.
- 한 애플리케이션에서 스프링 시큐리티의 다른 부분을 다양한 스타일로 혼합해 구성하는 사례를 보게 되는데 이는 바람직 하지 않다. 즉 유연성을 남용해서는 안된다. 이러한 옵션 중에서 선택하는 방법을 배워야 한다.
2.3.1 UserDetailsService 구성 요소 재정의
- 애플리케이션은 이 구성 요소를 인증 프로세스에 이용하고 있다.
자바는 인터페이스 객체 간의 계약을 정의하며 애플리케이션의 클래스 디자인에서 서로를 이용하는 개체를 분리하는 역할을 한다. 이 책에서 이러한 인터페이스의 특징을 강조하기 위해 주로 계약이라는 용어를 이용함
- 이 책 2장에서 선택한 방법으로는 직접 클래스를 구현하지 않고 스프링 시큐리티에 존재하는 InMemoryUserDetailsManager 구현을 이용한다. 이 구현은 UserDetailsService보다 복잡하지만, 여기에서는 크게 다를 바 없이 이용한다.
- 개념 증명용으로는 좋은 툴이다.
2.3.2 앤드포인트 권한 부여 구성 재정의
- 2.3.1절에서 설명한 것처럼 사용자에 대한 새로운 관리 방식을 소개했었다. 그 이후엔 앤드포인트의 인증 방식과 구성에 관해 논의할 수 있다.
- HTTP Basic 인증은 대부분의 애플리케이션 아키텍처에 적합하지 않다. 종종 애플리케이션에 맞게 변경하고 싶을 때가 있다. 마찬가지로 애플리케이션의 모든 앤드포인트를 보호할 필요는 없으며 보안이 필요한 앤드포인트에 다른 권한 부여 규칙을 선택해야 할수도 있다.
- 이러한 변경을 위해 WebSecurityConfigureAdapter 클래스를 확장해야 하는데 deprecated됨
2.3.4 AuthenticationProvider 구현 재정의
- 스프링 시큐리티 아키텍처에서 UserDetailsService 및 PasswordEncoder의 목적과 이를 구성하는 여러 방법을 배웠다면 이제 이들 구성요소에 위임하는 AuthenticationProvider도 맞춤 구성 할 수 있다는 것을 배워야한다.
- AuthenticationProvider는 인증 논리를 구현한다. AuthenticationManager에서 요청을 받은 후 사용자를 직접 찾는 작업을 UserDetailService에 암호를 검증하는 작업을 PasswordEncoder에 위임한다.
요약
- 스프링 시큐리티를 애플리케이션의 종속성으로 추가하면 스프링 부트가 약간의 기본 구성을 제공한다.
- 인증과 권한 부여를 위한 기본 구성 요소인 UserDetailsService, PasswordEncoder, AuthenticationProvider를 구현했다.
- User 클래스로 사용자를 정의할 수 있다. 사용자는 사용자 이름, 암호, 권한을 가져야한다 권한은 사용자가 애플리케이션의 컨텍스트에서 수행할 수 있는 작업을 지정한다.
- 스프링 시큐리티는 UserDetailsService의 간단한 구현 예인 InMemoryUserDetailsManager를 제공한다. UserDetaisService의 인스턴스와 같은 사용자를 추가해서 애플리케이션의 메모리에서 사용자를 관리할 수 있다.
- NoOpPasswordEncoder는 PasswordEncoder 계약(인터페이스)를 구현하며 암호를 일반 텍스트로 처리한다. 이 구현은 운영 단계에서는 적합하지 않다.
- AuthenticationProvider는 계약(인터페이스)를 이용해 애플리케이션의 맞춤형 인증 논리를 구현할 수 있다.
- 구성을 작성하는 방법은 여러가지가 있지만, 한 애플리케이션에서는 한 방법을 선택하고 고수해야 코드를 깔끔하고 이해하기 쉽게 만들 수 있다.