Hansel
스프링 시큐리티 / 작동 방식 본문
스프링 시큐리티는 어떻게 적용할까?
스프링 시큐리티는 특정 라이브러리를 추가하거나 Api를 호출하는 것이 아니다.
Spring Security Starter Dependency를 추가만 해주면
스프링 시큐리티가 알아서 모든 요청들에 대한 Intercepting을 하기 시작한다.
이 작업은 Filter를 통해 이루어진다.
Filter

필터는 단순한 서블릿 애플리케이션의 클래스인데 이 필터는 요청들을 인터셉트 할 수 있도록 해준다.
필터의 정의는 다음과 같다.
Servlet Filters are Java classes that can be used in Servlet Programming for the following purposes −
To intercept requests from a client before they access a resource at back end.
To manipulate responses from server before they are sent back to the client.
클라이언트의 요청이 서버의 자원에 접근하기 전에 가로채는 역할과
서버로부터의 응답이 클라이언트에게 보내지기 전에 조작하는 역할을 한다.
따라서 스프링 시큐리티를 프로젝트에 추가해주면
스프링 시큐리티는 DelegatingFilterProxy(서블릿 필터)를 사용하여 모든 요청에 대해 필터 처리를 해준다.
DelegatingFilterProxy의 정의는 다음과 같다.
Delegating filter proxy is a servlet filter that allows passing control to Filter classes
that have access to the Spring application context
Spring application context에 접근하는 필터들을 관리한다고 보면 된다.
DelegatingFilterProxy의 작동 방식
어떻게 이런식으로 작동할 수 있을까?
DelegatingFilterProxy 이름 자체에 힌트가 있다.

대표한다고 봐도 되겠지만 우리는 위임에 초점을 두자.
DelegatingFilterproxy는 모든 필터를 시작 시점에 catch하는데
그 작업을 혼자 다 하는게 아니라 특정 스프링 시큐리티 필터들에게 위임을 한다.
각 스프링 시큐리티 필터들은 다양한 작업들을 하는데 거기엔 Authentication과 Authorization이 존재한다.
Authentication

Authentication의 input과 ouput을 가정해본다면
input은 유저의 자격(Credential)이라 볼 수 있다. 예를 들어 로그인 ID나 패스워드 등을 말할 수 있다.
그렇다면 output은 뭐가 될까? 그 자격이 true인지 false인지 나타내는 Boolean타입이 될 수 있다.
하지만 실제 스프링 시큐리티의 작업은 이렇게 단순하진 않다.
인증이 완료되면 단순한 true를 리턴하는게 아니라 Principal을 return한다.
여기서 Principal이란 로그인된 유저의 정보를 의미한다.
인증객체(Authentication Object)는
인증 이전에는 유저의 자격 정보를 가지고 있지만
인증 이후에는 Principal을 가지게 된다.
인증은 누가 해주지?

그럼 정확하기 인증 자체를 해주는 것은 무엇일까?
바로 Authentication Provider이다.
이 인터페이스는 authenticate()라는 인증 메서드를 가지고 있다.
이 메서드가 유저의 자격 정보를 검증하는 일을 한다.
Authentication에서 유저의 자격을 보내온다면 Provider는 그 자격을 검증하고 반환하는 역할을 하게 된다.
중간 정리
- 유저가 정보(Credential)를 가지고 요청을 한다
- 스프링 시큐리티가 받아서 Authentication에 보낸다.
- Authentication은 그 정보를 authentication Provider에 보내서 authenticate 메서드를 실행한다.
- 정보가 괜찮다면 유저의 자격 정보를 담은 Principal을 생성하여 반환한다.
Authentication Provider?
지금까지 보면 Provider의 역할이 굳이 필요한가 싶기도 하다.
Authentication에서 자격 검증까지 하면 되지 않나 싶지만 유저가 보내는 자격의 정보는 매우 다양할 수 있다.
AuthenticationProvider는 단순 ID/PWD 방식의 credential만 다루는게 아니라
Oauth, LDAP auth 등의 방식들도 다룰 수 있다.
따라서 다양한 AuthenticationProvider를 두고 처리할 수 있다는 얘기이다.
이 다양한 providers를 다루기 위해 존재하는 것이 AuthenticationManager이다.

주어진 credential에 맞는 provider를 manager가 찾고 그 manager가 authenticate 메서드를
수행하는 방식이라 볼 수 있다. 이 작업을 위해 provider는 supports 메서드를 가진다.

그럼 provider는 authentication 작업을 하기 위해 무엇이 필요할까?
유저가 자격정보(credential)을 보내면 provider는 그 정보를 처리해야한다.
유저의 정보를 디비에서 가져와 일치하는지 확인하는 작업을 해야하는데
스프링 시큐리티에 그 작업은 UserDetailsService에서 처리한다.

이 객체는 유저의 username(ID)를 받아서 userDetails를 반환한다.
이 userDetails를 provider가 받는것이고 이것이 principal이라 볼 수 있다.
정리

- 필터가 인증 요청을 가로챈다.
- Authentication은 자격 정보를 받고 AuthenticationManager에게 전달한다.
- manager는 적합한 provider를 찾고(supports) 그 provider의 authenticate 메서드를 호출한다.
- 그 후 userDetailsService에 유저 자격 정보로 검증을 한다(loadByUserName()).
- 검증이 완료 되면 Principal(UserDetail)을 반환한다.
- 그 Principal을 이용하여 Authentication 타입의 객체를 생성하고 그 객체를 가지고 세션을 생성한다.
'Spring > Security' 카테고리의 다른 글
| 스프링 시큐리티 / 코드로 보는 동작 (0) | 2022.04.25 |
|---|---|
| 스프링 시큐리티 기초 용어 (0) | 2022.04.25 |