Sugar

[보안] SSO(Single Sign-On) - 하나의 인증 시스템에서 여러 서비스 지원하기

by Sugar0810

※ 개요

출처 : https://www.indusface.com/blog/what-is-single-sign-on/

#서버

  • 한 번의(Single) 로그인 인증(Sign-On)으로 여러 개의 서비스를 추가적인 인증 없이 사용할 수 있는 기술
  • 인증은 하나의 시스템(인증 서버)에서 수행하고, 그 인증 서버가 서비스를 각각 담당하는 서버에 인증 정보를 알려주는 방식

#클라이언트

  • 개별 사이트 별로 아이디/패스워드를 만들게 되면 잊기 쉬워 번거로움
  • 간편 인증을 통해 쉽게 가입
  • 연동된 타 서비스에도 추가 로그인 없이 이용 가능 

 

※ 사용 예시

  • 대형 회사들의 계정으로 통합 로그인

대형 회사들의 통합 인증 서비스

  • Gmail에 구글 계정으로 로그인을 하면, 유튜브, 구글 드라이브 등의 구글 서비스에 추가 로그인 없이 Gmail 로그인에 사용한 구글 계정을 동일하게 사용하는 것

 

 

※ 작동원리

#Delegation Model

출처 : https://user-images.githubusercontent.com/15958325/136686444-e8e9daf9-29cf-48a8-b50a-fe07941fcd06.png

  • 권한을 얻으려는 서비스의 인증 방식을 변경하기 어려울 때 많이 사용되는 모델
  • 대상 서비스의 인증 방식을 변경하지 않고 사용자의 인증 정보를 Agent가 관리하여 대신 로그인해 준다.
  • 만약 Target Service에 로그인하기 위한 정보가 admin/passwd라면, Agent가 해당 정보를 가지고 있고 로그인할 때 유저 대신 대상 서비스로 정보를 전달해 로그인시켜 줌

 

#Propagation Model

출처 : https://user-images.githubusercontent.com/15958325/136687288-b8b898bc-d6b2-4e93-a2e2-b15e9616fb5c.png

  • 통합 인증을 수행하는 곳에서 인증을 받아 “인증 토큰”이라는 것을 발급
  • 유저가 서비스에 접근할 때 발급받은 인증토큰을 서비스에 같이 전달하게 되고, 서비스는 토큰 정보를 통해 사용자를 인식할 수 있게 하는 방식

 

※ 구현

 

# SAML vs OAuth2.0 vs OIDC

  • SAML
    • 인증/인가 모두 제공, XML기반, Enterprise용 SSO구축에 주로 사용
    • 초기에는 SSO가 저변화되면서 많은 서비스들이 SSO 상용 서비스에서 제공하는 SAML(Security Assertion Markup Language) 방식을 사용
    • 간단한 정보 전달을 위해 많은 양의 태그가 사용되는 비효율성이 있다.
      • 이에 대한 개선책으로 SSO에서도 토큰을 사용
  • OAuth2.0
    • Authorization만 제공, JSON기반, 자격증명을 App과 공유하지 않고도 자원을 사용할 수 있게 해 줌
  • OpenID Connect
    • OAuth2.0과 함께 주로 사용, JSON기반, Mobile과 Native APP에서 사용될 수 있는 구조를 가짐

 

#토큰을 사용한 SSO 서비스 다이어그램

  • SSO의 직접적인 구현을 위해서 여러 가지 방법이 있겠지만, 이번 포스트는 인증 토큰(authentication token)을 사용
    • 페이스북, 유튜브를 비롯한 소셜미디어, 포탈, 이커머스 서비스의 가입자 기반 로그인 인증이 필요한 서비스들이 토큰 인증 방식을 많이 사용
    • 토큰(token)이란, 최초 인증이 성공한 사용자에게 일종의 증표로 인증 서버가 발급하는 정보
    • 토큰 방식은 서버가 각각 로그인한 사용자의 세션 정보를 따로 보관하지 않음
    • 한 번 인증 토큰을 클라이언트에게 발급하면, 클라이언트는 추후 요청부터는 그 토큰을 포함하고, 서버는 클라이언트 요청에 포함된 토큰을 필요할 때만 확인함

일반적인 사이트 인증

<토큰 발급 방식의 SSO 구현> 출처 : https://blog.naver.com/techtrip/221767776133

① 사용자는 Service1에 접속하여 로그인 버튼을 클릭한다.

② Service1은 인증 서비스(idP: Identity provider)로 해당 요청을 Redirect 한다.

③ 인증 서비스는 사용자에게 로그인 화면을 제공한다.

④ 사용자는 ID/PW (혹은 OAUTH2.0)을 입력한다.

⑤ 인증 서비스는 회원 DB와 비교하여 ID/PW가 올바르면 인증 토큰을 발급하며 Service1으로 돌려보낸다.

⑥ Service1은 발급된 토큰을 확인하고, 올바른 토큰이라면 사용자의 로그인 처리를 해준다.

⑦ 사용자는 Service2에 접속한다.

⑧ Service2는 이 사용자의 세션이 아직 유효한지 확인하고 유효하다면, Service2 용도의 토큰을 발급한다.

⑨ Service2는 발급된 토큰을 확인하고, 올바른 토큰이라면 사용자의 로그인 처리를 해준다.

 

하지만 여전히 세션이 필요한 이유가 있다.

한번 발급된 토큰만 믿을 수없기도 하고 일반적으로 토큰은 짧은 유효 시간을 갖는데 비해 서버에는 세션 정보를 오랫동안 보관하고 그 기간 내에 재접속한 사용자를 지원할 수 있기 때문이다.

 

유효 시간이 만료된 토큰 사용자가 다시 로그인하는 것은 불편하니 다음과 같은 방법을 사용한다.

  • 인증 서버는 ID/PW를 DB에서 확인하고, 정상 로그인이면 AccessToken과 RefreshToken을 발행
  • AccessToken은 exp가 짧다. 만료되면 RefreshToken으로 인증 서버에게 AccessToken를 재요청
  • RefreshToken은 exp가 상대적으로 길고, 인증 서버의 세션 정보를 포함
  • AccessToken 재요청을 받은 인증 서버는 RefreshToken과 세션 정보를 비교 후 재발급
  • RefreshToken 마저 유효 시간이 지나면, 사용자는 다시 ID/PW 로그인을 해야 한다.

한 번 로그인했던 서비스의 로그인이 상당 기간 다시 할 필요가 없는 것은 위의 방법을 사용하기 때문

브라우저의 쿠키와 temporary internet folder를 삭제하면 모든 토큰은 삭제된다. 때에 따라 AccessToken을 cookie에 저장하고, cookie는 브라우저가 닫히면 삭제되도록 설정할 수도 있다.

 

토큰에는 어떤 정보가 있고 어떻게 확인하나?

여기에서의 핵심은 토큰이 어떤 정보를 가지고 있고, 각 Service1과 Service2가 유효한 토큰임을 어떻게 확인할 것인지에 대한 디자인이다. 토큰의 종류는 여러 가지이지만 예제에선 JWT(JSON Web Token)을 사용하였다.

<인증 토큰의 내용과 유효성 검사 방법> 출처 : https://blog.naver.com/techtrip/221767776133

① 인증 서버(idP)와 각 Service 서버들은 사전에 비밀키(private key)를 공유한다.

② ID/PW로 정상적인 인증이 확인되면, 인증 서버는 토큰에 이메일, 이름, 유효 시간 등을 입력하여 발급한다.

③ 토큰을 Base64 Encoding 한다. 암호화가 아닌 인코딩이기 때문에 내용은 누구나 알 수 있다.

④ 토큰에 서명(signature) 부분을 추가하여 위 변조를 방지한다. 서명에 비밀키를 사용한다.

⑤ HTTPS 보안 채널로 토큰 확인을 요청한다. 토큰이 유실되더라도 비밀키가 없는 해커는 내용을 변조할 수 없다.

⑥ Service 서버는 비밀키로 토큰 변조 여부를 확인하고, 이메일 등의 사용자 정보 확인 후, 인증 처리를 해준다.

 

장점

가벼운 토큰을 사용하여 인증 처리 작업을 하는 서비스들이 부담을 갖지 않는 구조이고, 비밀키 없이는 토큰을 변조하지 못한다는 보안성이다.

 

단점

아무리 HTTPS로 토큰을 보낸다고 하더라도, 중간자 공격 등으로 토큰을 훔친 해커는 토큰을 변조하지 않고 그대로 사용한다면, 로그인한 사용자와 동일하게 보일 수 있다는 보안 취약점이다.

 

보완 방법 예시

동일한 토큰 정보에 대해서는 User-Agent 혹은 IP 주소를 확인한다.

어떤 웹 사이트의 경우 AccessToken이 유효하더라도 사용자의 IP 주소가 바뀌면 다시 로그인을 하도록 하는 것도 이런 이유 때문이다.

 


 

🎓 Reference

블로그의 정보

Sugar

Sugar0810

활동하기