일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- nginx
- gradle
- database
- Java
- nodejs
- Spring
- JavaScript
- Git
- IntelliJ
- wildfly
- Windows
- MySQL
- kubectl
- log4j2
- mybatis
- tibero
- LOG4J
- Kubernetes
- springboot
- intellijIDEA
- useEffect
- JPA
- gson
- docker
- jetbrains
- react
- NCP
- VSCode
- BPMN
- dbeaver
- Today
- Total
두 손끝의 창조자
웹 애플리케이션에서의 인증 절차와 Spring Security 본문
일반적인 웹 애플리케이션에 접속해서 인증을 받는 절차를 한번 상상해 보자.
- 자원요청 : home 페이지에 접속을 해서 열어보고 싶은 링크를 클릭한다.
- 요청자원인식 : 링크를 클릭하면 요청이 서버로가고, 서버는 사용자가 요청한 자원이 보호된 자원이라고 인식한다.
- 요청자원 제공 불가 알림 : 사용자가 인증되지 않은 상태라면, 서버는 사용자에게 인증, 즉 로그인을 하라고 알려준다. 이때 로그인 페이지로 이동될 수도 있고 아니면 그냥 에러 페이지를 띄울수 있다.
- 인증 인터페이스 : 인증 메커니즘에 따라서 ID와 패스워드를 입력하는 폼이 뜰수고 있고, 브라우저가 BASIC 인증 다이얼로그 박스나, 쿠키나, X.509 인증서 등을 뒤져서 신상을 파악한다.
- 인증요청 : 브라우저는 입력된 ID, 패스워드를 서버로 보내던지, HTTP 헤더에 인증정보를 실어서 보내던지 서버로 인증 정보를 보낸다.
- 인증처리 : 서버는 받은 인증정보가 유효한지 검사한다. 틀리면 다시 2번 으로 돌아간다.
- 자원 재요청 : 원래 요청했던 자원을 브라우저에게 내려준다. 단, 인증된 사용자가 요청한 자원에 대한 권한이 있어야 한다. 권한이 없으면 HTTP의 403 에러코드(권한없음)를 돌려준다.
스프링 시큐리티에는 위의 스텝에 맞는 클래스를 제공하는데 ExceptionTranslationFilter
,AuthenticationEntryPoint
클래스와 AuthenticationManager
를 호출하는 인증 메커니즘이다.
ExceptionTranslationFilter
스프링 시큐리티에서 발생시키는 모든 예외를 감지하는 스프링 시큐리티의 필터이다. 일반적으로 AbstractSecurityInterceptor
에 의해서 예외가 발생하는데, 이놈은 HTTP나 인증원리에 대해서는 알고있는 것이 없다. 대신에 ExceptionTranslationFilter
가 어떤 예외가 발생했는지, 예들들어 403 에러코드를 리턴해야하는지 AuthenticationEntryPoint
를 실행해야하는지 알아서 처리한다.
AuthenticationEntryPoint
위에서 3번째 단계를 담당하고 있는 클래스이다. 주요 인증 시스템에는 그것들만의 AuthenticationEntryPoint
의 구현을 가지고 있다.
Authentication Mechanism
브라우저가 ID/PASSWORD 폼을 보내든, HTTP 헤더에 인증정보를 보내든 서버로 정보를 주면 이것들을 모아서 처리하는 것이 필요한데 스프링 시큐리티에서는 이런 일을 하는 것을 인증 메커니즘이라고 한다. 예를들면 -form-base login-, -Basic authentication- 등이 있다. 인증 상세 정보가 모아지면 Authentication
오브젝트를 생성하고 AuthenticationManager
에 넘긴다.
인증 메커니즘이 인증처리에 성공을 하면 Authentication
오브젝트는 완전체로 되고 인증이 유효한것으로 인식한다. 이어서 SecurityContextHolder
에 Authentication
를 넣고 위의 7번 단계를 수행한다.
요청간 인증정보 공유
애플리케이션 종류에 따라서 다르겠지만 인증 정보를 저장하는 전략이 필요하다. 일반적인 웹 애플리케이션은 한번 로그인을 하면 인증 정보를 세션ID로 구분한다. 스프링 시큐리티는 SecurityContextPersistenceFilter
로 인증정보를 저장하고 불러온다. 요청마다 SecurityContextHolder
로 복원하고 요청이 완료되면 SecurityContextHolder
를 지운다. 인증정보에 접근하기 위해서 HttpSession
에 직접 접근해서 무언가 하는 것은 위험할 수 있으니 안하는 것을 추천한다.
무상태 RESTfull web service 같은 것은 HTTP 세션을 사용하지 않고 요청마다 인증처리를 한다. 그렇다 하더라도 요청에 대한 처리가 끝나면 SecurityContextHolder가 지워지도록 SecurityContextPersistenceFilter 을 사용해야 한다.