[개요]
서비스 개발을 하면서 필수적으로 보안적인 부분을 생각할 수 밖에 없다. 이때 서비스에서 보안 중 가장 가깝게 생각해볼 수 있는 것이 인증과 인가이다. 여기에선 인증과 인과에 대해 알아보고, 변화과정과 장단점을 알아보려 한다.
[개념]
나는 A이다. 서비스에서 B라는 자원을 조회할 것이다. 근데 서비스의 B라는 자원을 불러오기 위해선 해당 서비스의 유저여야하고, admin이라는 권한을 가지고 있어야 한다. B 자원을 조회한 뒤, A는 admin 권한이 필요한 C 자원도 조회할 것이다. 서비스는 유저가 B와 C라는 자원을 접근할 때 무엇인가 확인을 해야 할 것이다.
1. 인증
인증이란 식별 가능한 데이터로 서버에 등록된 유저의 신원을 입증하는 과정이다. 서비스의 B 리소스를 불러오기 위해선 A는 admin이라는 권한을 가지고 있어야 한다. 그런데 서비스 내 리소스 접근 권한에 대해 알아보기 전에 지금 접속한 유저가 A인지 확인해야 한다. 유저에 대한 정보는 서버에서 어떠한 형식으로든 저장을 하고 있을 것이고, A는 이를 증명하면 된다. 가장 고전적인 방법인 아이디 / 비밀번호 방식으로 A가 인증 요청을 했다고 하자. 그렇다면 요청 온 데이터와 기존에 서버가 저장한 데이터를 비교하여 유저인지를 확인할 것이다. 이 절차가 인증이다.
2. 인가
인가란 인증된 사용자에 대한 자원 접근 권한 확인을 의미한다. A는 서비스로부터 자신이 A라는 것을 인증 받았다. 그때 A는 admin이라는 권한을 갖고 있다는 것이 확인 되어 B 자원 조회를 성공했다. 이후 A는 C라는 자원을 조회하려 한다. 이 자원도 admin의 역할이 필요하다. 그런데 서비스에서 다시 인증을 요청한다. 유저는 다시 아이디와 비밀번호를 응답해야 한다. 유저 입장에서 한 번 인증한 서비스를 다시 인증하면서까지 불편함을 감수하며 보안을 신경 쓸 필요가 있을까? 아니 애초에 다시 인증한다는 것이 보안적으로 가장 좋은 방법이 맞을까?
이를 해결하는 방식이 인가이다. 인증이 성공했다면 해당 유저가 인증된 유저라는 표시로 인증서를 줄 것이고, 이를 브라우저의 저장소에 저장하여 권한이 필요한 요청마다 이를 포함하여 요청한다. 이때 로그인에 필요한 아이디나 비밀번호 등의 개인 정보가 아닌 다른 암호화 된 값을 사용한다. 이때 Session(세션) 또는 Token(토큰)이 사용된다. 이에 대한 설명은 아래에 이어서 하려 한다.
[변화 과정]
1. 인증을 위해 HTTP Request header나 body에 ID와 PW를 암호화하여 보내는 방법
서비스의 특정 리소스의 접근에는 회원에게만 제공하기 위한 정보가 있다. 이를 확인하기 위한 방법으로는 로그인으로 유저를 인증하는 방법이 있다. 서비스 내에 저장 되어 있는 유저인지 확인하는 방법으로 가장 대표적인 것이 바로 ID와 PW를 이용한 로그인이다. 이 둘을 암호화 하여 HTTP header나 body에 담고, 이 암호 알고리즘을 서버에서 알고 있다면 이를 복호화 하여 인증이 가능하다. 그러나 이 방법은 다음과 같은 단점이 있다.
- 인증이 유지 되지 않는다. 다른 기능을 이용하기 위해서 또 유저가 ID와 PW를 입력하여 요청을 보내야 한다
- 해커가 중간에 가로채면 날 것의 데이터를 암호화 한 것이기 때문에 위험하다.
2. 인가(인증 유지)를 위해 Client Browser의 저장소를 이용하는 방법 - Cookie
1번에서의 단점은 인증이 유지 되지 않는 것이었다. 이를 해결할 수 있는 방법이 있다. 클라이언트의 로그인 등으로 서버에서 인증을 완료한 다음에 클라이언트 쪽에서 쿠키에 ID와 PW를 암호화 하여 넣어 보내면 클라이언트는 이를 브라우저의 쿠키 저장소에 저장하여 권한이 필요한 것을 이용할 때마다 이를 담아 보낼 수 있다. 즉, 유저는 다른 기능을 이용할 때 더 이상 ID와 PW를 따로 입력해주지 않아도 된다. 처음의 인증 시에만 입력해주면 된다. 그러나 이 부분도 다음과 같은 단점이 있다.
- 해커가 중간에 가로채면 날 것의 데이터를 암호화 한 것이기 때문에 위험하다.
3. 인가를 위해 Session 사용하는 방법
2번의 단점은 로그인에 직접적으로 사용 되는 ID와 PW를 암호화 하여 보냈다는 것이다. 이를 사용하여 서버에서는 직접 유저를 확인하며 인증을 진행하고, 인가까지 했던 것이다. 그러나 세션을 사용하면 이를 완화할 수 있다. 바로 유저를 식별할 수 있는 user id 등의 정보로 세션을 생성하고 key-value 형식으로 관리할 수 있기 때문이다. 이는 서버에서 유효성 만료 시간도 관리하기 때문에 문제가 있을 시 해당 세션을 삭제해버리면 더이상 유효하지 않는 세션으로 만들 수 있다. 즉, 서버에서 유저의 인가에 대한 유효성을 직접 제어할 수 있다. 그러나 이는 다음과 같은 단점이 있다.
- 서비스의 성장으로 서버가 늘어나면 세션은 보통 메모리로 관리 되기 때문에 모든 서버의 데이터를 동기화 해줘야 한다.
- 인증과 인가만을 위한 서버를 따로 두면 위의 단점을 해결할 수 있지만, 정말 많은 유저가 몰린다면 서버의 부하가 늘어난다. 이렇게 되면 서버의 부하가 몰려 문제가 발생할 시 인증과 인가를 할 수 없으므로 서비스가 먹통되는 일이 생긴다.
4. 인가를 위해 Token을 사용하는 방법
1 번은 단순 요청 및 응답으로 인증을 진행했고, 2 번은 클라이언트의 브라우저 저장소를 이용하여 직접적인 인증 정보인 ID 및 PW로 인가를 관리했고, 3번은 세션으로 서버에서 정보를 관리했다. 4번은 서버에서 암호화 관련된 정보만을 알고 있고, 유저가 인증을 완료할 시 서버에서 토큰을 클라이언트에게 넘기는 방식이다. 서버에서는 이에 대한 정보를 저장하고 있지 않기 때문에 HTTP의 stateless에 대한 특성도 지키게 된다. 때문에 서버가 여러 대가 되어도 해당 token을 읽을줄만 안다면 인가를 쉽게 이뤄낼 수 있다. token에는 권한과 만료기간, 그리고 최소한의 유저를 식별할 수 있는 데이터가 암호화 되어 들어가 있다. 이를 Access token이라 하는데 이를 탈취 당한다면 더이상 해커와 유저를 구별할 수 없다. 이를 개발자는 고객의 책임으로 돌린다. 신용카드를 사용하다 잃어버리면 카드사 책임이 아니듯 말이다. 그래서 이를 해결하기 위해 만료기간을 짧게하고, refresh token을 다루는 방식도 이용하지만 refresh token을 탈취 당하면 이것도 동일한 문제를 갖는다. 탈취를 당해도 알아보기 힘들도록 HTTPS를 사용하는 것도 최선의 방법이다.
[결론]
서비스에서 리소스 접근 권한을 관리하기 위해선 인가를 세션이나 토큰 형식으로 구현해야 하고, 인가를 구현하기 위해선 인증을 구현해야 한다. 그렇기 때문에 앞으로 Spring Security를 이용하여 보안적인 부분을 구현하려 한다. 세부적으로는 OAuth를 이용한 인증과 JWT를 이용한 인가를 어떻게 구현하는지 정리하도록 하겠다. PA 서비스에서는 유저의 통계 자료를 관리하기 위해 서버와 DB의 부하가 꽤나 클 것으로 예상 된다. 때문에 이후 목표를 하고 있는 동접자 수를 생각하면 서버의 증축이 발생할 수도 있다. 그래서 세션 보다는 토큰 방식을 사용할 것이다. 서버 부하를 최소한으로 하고, 확장성도 챙길 수 있기 때문이다.
'보안(인증, 인가, Spring security)' 카테고리의 다른 글
Spring security architecture 해석 part1 (0) | 2024.02.25 |
---|---|
[Spring security] 인가 - 특정 리소스 마다 권한 설정하기 (0) | 2024.02.13 |
[개요]
서비스 개발을 하면서 필수적으로 보안적인 부분을 생각할 수 밖에 없다. 이때 서비스에서 보안 중 가장 가깝게 생각해볼 수 있는 것이 인증과 인가이다. 여기에선 인증과 인과에 대해 알아보고, 변화과정과 장단점을 알아보려 한다.
[개념]
나는 A이다. 서비스에서 B라는 자원을 조회할 것이다. 근데 서비스의 B라는 자원을 불러오기 위해선 해당 서비스의 유저여야하고, admin이라는 권한을 가지고 있어야 한다. B 자원을 조회한 뒤, A는 admin 권한이 필요한 C 자원도 조회할 것이다. 서비스는 유저가 B와 C라는 자원을 접근할 때 무엇인가 확인을 해야 할 것이다.
1. 인증
인증이란 식별 가능한 데이터로 서버에 등록된 유저의 신원을 입증하는 과정이다. 서비스의 B 리소스를 불러오기 위해선 A는 admin이라는 권한을 가지고 있어야 한다. 그런데 서비스 내 리소스 접근 권한에 대해 알아보기 전에 지금 접속한 유저가 A인지 확인해야 한다. 유저에 대한 정보는 서버에서 어떠한 형식으로든 저장을 하고 있을 것이고, A는 이를 증명하면 된다. 가장 고전적인 방법인 아이디 / 비밀번호 방식으로 A가 인증 요청을 했다고 하자. 그렇다면 요청 온 데이터와 기존에 서버가 저장한 데이터를 비교하여 유저인지를 확인할 것이다. 이 절차가 인증이다.
2. 인가
인가란 인증된 사용자에 대한 자원 접근 권한 확인을 의미한다. A는 서비스로부터 자신이 A라는 것을 인증 받았다. 그때 A는 admin이라는 권한을 갖고 있다는 것이 확인 되어 B 자원 조회를 성공했다. 이후 A는 C라는 자원을 조회하려 한다. 이 자원도 admin의 역할이 필요하다. 그런데 서비스에서 다시 인증을 요청한다. 유저는 다시 아이디와 비밀번호를 응답해야 한다. 유저 입장에서 한 번 인증한 서비스를 다시 인증하면서까지 불편함을 감수하며 보안을 신경 쓸 필요가 있을까? 아니 애초에 다시 인증한다는 것이 보안적으로 가장 좋은 방법이 맞을까?
이를 해결하는 방식이 인가이다. 인증이 성공했다면 해당 유저가 인증된 유저라는 표시로 인증서를 줄 것이고, 이를 브라우저의 저장소에 저장하여 권한이 필요한 요청마다 이를 포함하여 요청한다. 이때 로그인에 필요한 아이디나 비밀번호 등의 개인 정보가 아닌 다른 암호화 된 값을 사용한다. 이때 Session(세션) 또는 Token(토큰)이 사용된다. 이에 대한 설명은 아래에 이어서 하려 한다.
[변화 과정]
1. 인증을 위해 HTTP Request header나 body에 ID와 PW를 암호화하여 보내는 방법
서비스의 특정 리소스의 접근에는 회원에게만 제공하기 위한 정보가 있다. 이를 확인하기 위한 방법으로는 로그인으로 유저를 인증하는 방법이 있다. 서비스 내에 저장 되어 있는 유저인지 확인하는 방법으로 가장 대표적인 것이 바로 ID와 PW를 이용한 로그인이다. 이 둘을 암호화 하여 HTTP header나 body에 담고, 이 암호 알고리즘을 서버에서 알고 있다면 이를 복호화 하여 인증이 가능하다. 그러나 이 방법은 다음과 같은 단점이 있다.
- 인증이 유지 되지 않는다. 다른 기능을 이용하기 위해서 또 유저가 ID와 PW를 입력하여 요청을 보내야 한다
- 해커가 중간에 가로채면 날 것의 데이터를 암호화 한 것이기 때문에 위험하다.
2. 인가(인증 유지)를 위해 Client Browser의 저장소를 이용하는 방법 - Cookie
1번에서의 단점은 인증이 유지 되지 않는 것이었다. 이를 해결할 수 있는 방법이 있다. 클라이언트의 로그인 등으로 서버에서 인증을 완료한 다음에 클라이언트 쪽에서 쿠키에 ID와 PW를 암호화 하여 넣어 보내면 클라이언트는 이를 브라우저의 쿠키 저장소에 저장하여 권한이 필요한 것을 이용할 때마다 이를 담아 보낼 수 있다. 즉, 유저는 다른 기능을 이용할 때 더 이상 ID와 PW를 따로 입력해주지 않아도 된다. 처음의 인증 시에만 입력해주면 된다. 그러나 이 부분도 다음과 같은 단점이 있다.
- 해커가 중간에 가로채면 날 것의 데이터를 암호화 한 것이기 때문에 위험하다.
3. 인가를 위해 Session 사용하는 방법
2번의 단점은 로그인에 직접적으로 사용 되는 ID와 PW를 암호화 하여 보냈다는 것이다. 이를 사용하여 서버에서는 직접 유저를 확인하며 인증을 진행하고, 인가까지 했던 것이다. 그러나 세션을 사용하면 이를 완화할 수 있다. 바로 유저를 식별할 수 있는 user id 등의 정보로 세션을 생성하고 key-value 형식으로 관리할 수 있기 때문이다. 이는 서버에서 유효성 만료 시간도 관리하기 때문에 문제가 있을 시 해당 세션을 삭제해버리면 더이상 유효하지 않는 세션으로 만들 수 있다. 즉, 서버에서 유저의 인가에 대한 유효성을 직접 제어할 수 있다. 그러나 이는 다음과 같은 단점이 있다.
- 서비스의 성장으로 서버가 늘어나면 세션은 보통 메모리로 관리 되기 때문에 모든 서버의 데이터를 동기화 해줘야 한다.
- 인증과 인가만을 위한 서버를 따로 두면 위의 단점을 해결할 수 있지만, 정말 많은 유저가 몰린다면 서버의 부하가 늘어난다. 이렇게 되면 서버의 부하가 몰려 문제가 발생할 시 인증과 인가를 할 수 없으므로 서비스가 먹통되는 일이 생긴다.
4. 인가를 위해 Token을 사용하는 방법
1 번은 단순 요청 및 응답으로 인증을 진행했고, 2 번은 클라이언트의 브라우저 저장소를 이용하여 직접적인 인증 정보인 ID 및 PW로 인가를 관리했고, 3번은 세션으로 서버에서 정보를 관리했다. 4번은 서버에서 암호화 관련된 정보만을 알고 있고, 유저가 인증을 완료할 시 서버에서 토큰을 클라이언트에게 넘기는 방식이다. 서버에서는 이에 대한 정보를 저장하고 있지 않기 때문에 HTTP의 stateless에 대한 특성도 지키게 된다. 때문에 서버가 여러 대가 되어도 해당 token을 읽을줄만 안다면 인가를 쉽게 이뤄낼 수 있다. token에는 권한과 만료기간, 그리고 최소한의 유저를 식별할 수 있는 데이터가 암호화 되어 들어가 있다. 이를 Access token이라 하는데 이를 탈취 당한다면 더이상 해커와 유저를 구별할 수 없다. 이를 개발자는 고객의 책임으로 돌린다. 신용카드를 사용하다 잃어버리면 카드사 책임이 아니듯 말이다. 그래서 이를 해결하기 위해 만료기간을 짧게하고, refresh token을 다루는 방식도 이용하지만 refresh token을 탈취 당하면 이것도 동일한 문제를 갖는다. 탈취를 당해도 알아보기 힘들도록 HTTPS를 사용하는 것도 최선의 방법이다.
[결론]
서비스에서 리소스 접근 권한을 관리하기 위해선 인가를 세션이나 토큰 형식으로 구현해야 하고, 인가를 구현하기 위해선 인증을 구현해야 한다. 그렇기 때문에 앞으로 Spring Security를 이용하여 보안적인 부분을 구현하려 한다. 세부적으로는 OAuth를 이용한 인증과 JWT를 이용한 인가를 어떻게 구현하는지 정리하도록 하겠다. PA 서비스에서는 유저의 통계 자료를 관리하기 위해 서버와 DB의 부하가 꽤나 클 것으로 예상 된다. 때문에 이후 목표를 하고 있는 동접자 수를 생각하면 서버의 증축이 발생할 수도 있다. 그래서 세션 보다는 토큰 방식을 사용할 것이다. 서버 부하를 최소한으로 하고, 확장성도 챙길 수 있기 때문이다.
'보안(인증, 인가, Spring security)' 카테고리의 다른 글
Spring security architecture 해석 part1 (0) | 2024.02.25 |
---|---|
[Spring security] 인가 - 특정 리소스 마다 권한 설정하기 (0) | 2024.02.13 |