Spring Academy) Simple Spring Security
https://spring.academy/courses/building-a-rest-api-with-spring-boot/lessons/simple-spring-security
Simple Spring Security - Building a REST API with Spring Boot - Spring Academy
Learn the differences between authentication and authorization, and how Spring Security can protect against common security vulnerabilities.
spring.academy
프로젝트에 스프링 시큐리티를 적용하기 전에 스프링 아카데미 홈페이지의 문서를 읽어보고 나름대로 번역해서 정리해봤다.
*** 사이의 글은 제 생각 적었습니다.
Authentication (인증)
API 의 사용자는 어떤 사람일수도 있고 다른 프로그램일 수도 있다.
이런 사용자를 Principal 이라고 한다.
Authentication 이란 Principal 이 시스템에게 자신을 증명하는 행동이다.
이걸 수행하는 방법중 하나는 credential 을 시스템에게 제공하는 것이다.
아이디와 비밀번호가 credential 이고 아이디 비밀번호 방식을 Basic Authentication
이라고 한다.
알맞은 credential 이 시스템에게 제공되면 principal 이 인증됐다 즉 로그인 됐다고 말한다.
http 는 무상태 프로토콜 이므로 요청이 올때마다 요청에 credential 이 포함되어야 한다.
하지만 이렇게 하면 너무 비효율적이므로 인증이 한 번 완료되면 Authentication Session 이 생성된다.
세션은 여러가지 방식으로 생성 될 수 있는데 가장 기본적이고 많이 사용되는 방식은 쿠키에 세션토큰을 집어넣는 방식이다.
- 쿠키는 따로 명시하지 않아도 모든 요청에 자동 포함되어 서버에 전송된다
- 서버는 쿠키의 세션토큰이 유효한지 확인하고 그렇지 않다면 요청을 거부할수 있다
- 쿠키는 웹페이지를 닫았다가 나중에 다시 방문해도 일정시간 유지될수 있다
Spring Security and Authentication
스프링 시큐리티는 Filter Chain 에서 인증을 구현한다.
필터는 개발자가 컨트롤러 보다 먼저 호출되는 메서드를 정의할수 있는 Java 의 웹 아키텍처의 구성 요소 이다.
체인의 각 필터는 요청 처리를 계속할지 거부할지 결정할수 있다.
스프링 시큐리티는 사용자 인증을 확인하는 필터를 만들어 요청이 인증되지 않은 경우에 401 UNAUTHORIZED 응답을 보낸다.
Authorization (인가)
Authentication (인증) 이 완료된후 Authorization (인가) 가 발생한다.
***
(OAuth2 도 유저를 인증받은 증거로 토큰을 얻고, 토큰을 기반으로 리소스 접근의 인가를 받는 방식이다)
https://tose33.tistory.com/1303
Google OAuth2
구글 로그인 구현 https://lsh-instaweb.herokuapp.com/login 로그인 lsh-instaweb.herokuapp.com OAuth (Open Authorization) 만든 웹사이트에 구글로 로그인을 구현하고 싶어서 이에 대해서 공부해봤다. 요즘 많은 웹사이
tose33.tistory.com
***
스프링 시큐리티는 RBAC (Role-Based-Acess-Control) 로 Authorization 을 제공한다.
Principal 은 여러개의 Role 을 갖고, 각 리소스들은 해당 리소스에 접근 하기 위해 Principal 이 어떤 Role 을 갖고 있어야 하는지 정해져있다.
예를들어 관리자 권한 role 을 갖는 사람과, 카드소유자 role 을 갖는 사람이 있으면 전자가 더 많은 리소스에 접근할수 있을 것이다.
Role 은 개발자가 메소드별로 부여할수도 있고 글로벌 레벨로 부여할 수도 있다.
Same Origin Policy
웹은 많은 공격자들이 항상 취약점을 찾고 있는 위험한 곳이다!
웹의 가장 기본적인 보안 중 하나는 HTTP 클라이언트와 서버가 SOP (Same origin policy) 을 구현하는 것이다.
***
SOP 는 서로 다른 도메인의 요청을 거부하는 것이다. 이것을 위반시 CORS 에러를 만날수 있다
***
SOP 가 없다면 누구나 어떤 하나의 웹 페이지에서 다른 웹 페이지로 요청을 보낼수 있다.
예를 들어보자.
만약에 누군가 은행 홈페이지에 로그인 한 후에 새탭이나 새 윈도우로 어떤 수상한 웹 페이지에 방문한다.
로그인을 했기 때문에 현재 쿠키에는 세션토큰이 포함되어 있을것이다.
만약 SOP가 없다면 수상한 웹 페이지에서 세션토큰이 있는 쿠키를 포함해서 은행 홈페이지 서버에 요청을 보낼수 있게된다.
Cross Origin Resource Sharing
그런데 어떤 경우에는 다른 도메인의 요청을 허용해야 할 수도 있다.
CORS 로 서버에서 요청을 받을 도메인을 설정할수 있다.
스프링 시큐리티는 @CrossOrigin 애노테이션으로 요청을 허용할 도메인을 설정할수 있게 해준다.
***
아래는 이전에 스프링 시큐리티를 적용하지 않은 프로젝트에서 CORS 를 허용한 코드다.
***
Common Web Exploits
웹의 악의적인 공격자들은 이미 알려진 보안 취약점을 악용하는 것과 더불어 새로운 취약점도 끊임없이 발견하고 있다.
스프링 시큐리티는 이런 악용을 방어 할 수 있는 도구들을 제공한다.
두가지 일반적인 악용방식과 스프링 시큐리티가 어떻게 이것들을 방어하는지 알아보자.
Cross-Site Request Forgery
vulnerability (취약점) 의 한 유형은 세션 라이딩이라고도 알려진 Cross-Site Request Forgery 이다.
세션 라이딩은 쿠키에 의해 활성화되는데, CSRF 공격은 유저가 이미 로그인한 (즉 인증을 받은) 상태일때 malicious code (수상한 코드)가 서버에 요청을 보낼때 발생한다.
서버는 이렇게 이미 인증을 받은 Authentication cookie 를 받으면 유해한 요청인지 아닌지 판단할수 있는 방법이 없다.
이런 CSRF 공격을 보호하기 위한 방법으로 CSRF 토큰을 사용하는 방법이 있다.
CSRF 토큰은 각 요청마다 고유한 토큰이 생성되기 때문에 세션토큰과 다르다.
각 요청마다 생성되기 때문에 외부 공격자가 클라이언트와 서버간의 대화(요청 응답)에 끼어들기가 더 어려워진다.
스프링 시큐리티는 기본적으로 CSRF 토큰을 지원하는 기능이 내장되어 있다.
***
구글링했을때 스프링 시큐리티가 csrf 토큰을 세션마다 만든다, 요청마다 만든다에 대해 서로 다른 얘기들이 있었다.
Cross-Site Scripting
CSRF 보다 아마도 더 위험한 취약점이 Cross-Site Scripting(XSS) 이다.
공격자가 어떠한 방식으로 피해자의 어플리케이션을 속여서 임의의 코드를 실행시킬수 있을때 발생한다.
이것을 수행할수 있는 여러가지 방식이 있는데 가장 간단한 방식은 <script> 태그를 포함한 문자열을 DB에 저장해놓고,
해당 문자열이 웹 페이지에 렌더링 되는 것을 기다리는 방식이다.
XSS 는 CSRF 보다 잠재적으로 더 위험하다.
CSRF 는 서버에서 사용자에게 인가된 리소스 접근만이 수행될수 있는 반면
XSS 는 임의의 코드가 클라이언트에서 실행될수도 있고 서버로 전달되 서버에서 실행될수도 있다.
또한 XSS 공격은 Authentication 과 상관없이 이루어진다.
XSS 공격은 잘못된 프로그래밍으로 발생된 프로그램의 '구멍' 에 의해 발생된다.
XSS 공격을 방어하는 주된 방법은 외부소스(웹 양식, uri 쿼리 스트링) 의 모든 데이터를 검사하는 것이다.
위의 <script> 태그의 예시의 경우 문자열이 랜더링 될 때 <script> 를 이스케이프 시킬수 있다.
***
<script> 를 <script> 로 바꾼다.
이렇게 함으로서 해당 문자열은 <script> 태그를 의미하지 않고 그냥 문자열을 의미하게 되고 스크립트가 실행되지 않는다.
***