Spring Security ::

막강한 인증(Authentication)과 인가(Authorization, 권한 부여) 기능을 가진 프레임워크이다. 보안을 위한 표준이라고 할 수 있다. 인증과 인가의 의미 차이가 없는 줄 알았는데 공부를 하면서 아주 큰 차이가 있다는 것을 알았다.

인증(Authentication) _ 해당 사용자가 본인이 맞는지를 확인하는 절차를 의미한다.

인가(Authorization) _ 인증된 사용자가 요청한 자원에 접근 가능한지를 결정하는 절차를 의미한다. '인증된 사용자' 단어에서 알 수 있듯이, [인증]에서 성공될 시에 [인가]로 넘어갈 수 있다.

"인증 → 인가" , 인증과 인가를 위해 principal을 아이디로, credential을 비밀번호로 사용하는 credential 기반의 인증방식을 사용한다.

principal :: 보호받는 resource에 접근하는 대상

credential :: resource에 접근하는 대상의 비밀번호

 

OAuth ::

OAuth는 사용자가 요청권한이 있는지를 확인하는 인가(Authorization) 프로토콜이다. 

위키백과의 사전적 정의에 따르면, 인터넷 사용자들이 비밀번호를 제공하지 않고 다른 웹사이트 상의 자신들의 정보에 대해 웹사이트나 어플리케이션의 접근 권한을 부여할 수 있는 공통적인 수단으로서 사용되는(접근 위임을 위한) 개방형 표준이다.

 

> OAuth에 관련된 용어 

  • 사용자(user) _ 서비스 제공자와 소비자를 사용하는 계정을 가지고 있는 개인을 말한다.
  • 소비자(consumer) _ Opne API를 이용하여 개발된 OAuth를 사용하여 서비스 제공자에게 접근하는 웹사이트 또는 어플리케이션을 의미한다.
  • 서비스 제공자 (service provider) _ OAuth를 통해 접근을 지원하는 웹 어플리케이션(Open API를 제공하는 서비스이다. 대표적인 예시로 'Google', 'Naver', 'Kakao'..)
  • 소비자 비밀번호(consumer secret) _ 서비스 제공자에게 소비자가 자신임을 인증하기 위한 키를 말한다.   
  • 요청 토큰(request token) _ 소비자가 사용자에게 접근권한을 인증받기 위해 필요한 정보가 담겨있으며 후에 접근 토큰으로 변환된다.
  • 접근 토큰(access token) _ 인증 후에 사용자가 서비스 제공자가 아닌 소비자를 통해서 보호된 자원에 접근하기 위한 키를 포함한 값이다.

> OAuth의 인증방식 = 인증 과정을 '타 서비스에게 위임'하는 인증 방식이다.

OAuth의 인증은 소비자와 서비스 제공자 사이에서 일어난다.

  1. 소비자가 서비스제공자에게 요청토큰을 요청한다.
  2. 서비스제공자가 소비자에게 요청토큰을 발급해준다.
  3. 소비자가 사용자를 서비스제공자로 이동시킨다. 여기서 사용자 인증이 수행된다.
  4. 서비스제공자가 사용자를 소비자로 이동시킨다.
  5. 소비자가 서비스제공자에게 접근토큰을 요청한다.
  6. 서비스제공자가 접근토큰을 발급한다.
  7. 발급된 접근토큰을 이용하여 소비자에게 사용자 정보에 접근한다.

'위임한다'는 뜻 그대로 사용자가 서비스 제공자에 직접 로그인하는 것은 아니다. 웹 사이트(소비자)에 접속한 사용자의 정보는 여전히 내 웹 사이트에서 관리해야 한다. 

서비스 제공자(구글, 카카오..)가 해주는 일은 사용자가 '소셜 로그인' 기능을 통해 서비스 제공자에게 전송된 계정 정보가 유효한지(예를 들어, 구글 아이디 및 비밀번호가 일치하는지)를 확인한 후에 유효하다면 서비스 제공자가 가진 사용자의 정보 중 일부(유저 이름, 프로필 이미지 등)를 소비자(웹 서비스, 어플리케이션)에게 제공해주는 '인증' 과정만을 처리해주는 것이다.

 

>승인된 리디렉션 URI

'스프링 부트와 AWS로 혼자 구현하는 웹서비스' 책으로 실습을 하면서 이 부분에 대해서 제대로 이해를 하지 못하였다.

1. 서비스에서 파라미터로 인증 정보를 주었을 때 인증이 성공하면 구글에서 리다이렉트할 URL입니다.

2. 사용자가 별도로 리다이렉트 URL을 지원하는 Controller를 만들 필요가 없습니다. 시큐리티에서 이미 구현한 상태입니다.

이 두가지 부분에 대해서 이해를 하지 못했다. 공부를 하면서 추측하건대, 2번은 Controller에서 PostMapping 구현을 말하는 것이다.

실습을 하면서 궁금했던 부분이기에 서비스 제공자가 아닌 구글로 특정 지어 설명할 것이다.

구글 계정으로 로그인하는 서비스를 만들기 위해서 구글 클라우드 플랫폼에서 프로젝트(OAuth 클라이언트)를 생성하였다. 이 때, 구글에서 'clientID'와 '승인된 리디렉션 URI 지정'을 제공해준다. 

  • client ID

서비스를 사용하면서 [구글 로그인]을 누르면, 구글 인증 페이지가 뜨는데, 이는https://accounts.google.com/o/oauth2/auth URL에서 제공한다. 이를 단순히 이 링크를 주소창에 치면

다음과 같은 에러 페이지가 뜨는 것을 확인할 수 있다. 이 에러가 난 이유는 우리가 구글 로그인 기능을 사용하기 위해서 Google 인증 서버 페이지에 접속한다는 것은 특정 웹사이트에서 구글 계정을 사용한 OAuth인증을 사용하고 싶다는 것을 의미한다. 그런데 주소창에 바로 인증 서버 페이지 주소를 입력하면 어떤 웹 사이트에서 OAuth인증을 요청하는지 알 수 없기 때문에 오류가 발생한 것이다. 

이 때, '어떤 웹 사이트에서 OAuth 인증을 요청하는가'를 Google 인증 서버에 알려주기 위해 사용하는 것이 '클라이언트 ID'이다. 웹서비스를 프로젝트로 등록하고, 등록할 때에 웹 사이트의 URL 정보를 제공했기 때문에 서버에 구글의 클라이언트 ID만 등록해주면, 구글에서 어떤 웹 사이트에서 OAuth 인증을 요청하는지를 자체적으로 식별할 수 있게 된다.

  • 승인된 리디렉션 URI

OAuth를 사용하기 위해서는 구글 인증 서버에 client ID 이외에도 많은 추가 정보들을 제공해줘야 하지만, 그 중 중요한 정보가 리디렉션 URI이다. 

웹 사이트 사용자가 구글 인증 서버에 올바른 계정 정보를 입력하면, 구글에서는 이 정보가 유효한지 판단한 후에 유효하다면 해당하는 유저의 정보를 웹서비스로 전송해야 한다. 그래야 웹 서비스에서도 현재 로그인한 사용자가 어떤 사용자인지 식별할 수 있으며, 자체적으로 유저 정보를 관리할 수 있기 때문이다. 그러면, 구글 유저 정보를 웹 서비스의 특정 URL로 전송해줘야 하는데 이 URL이 바로 리디렉션 URL이다. 구글은 인증이 끝나면 리디렉션 URL로 로그인을 한 구글 계정 정보를 POST로 전송해준다.

 

Open ID ::

OAuth는 권한 관리를 위한 프로토콜이라면, OpenID는 인증을 위한 프로토콜이라고 할 수 있다. Open ID 프로토콜에 대한 정의는 OAuth 2.0 프로토콜의 상위계층에서 인증을 담아내는 프로토콜이라고 한다. 즉, OAuth API에 OpenID API가 포함되어 있다고 생각하면 되고, 실제로 그렇기도 하다.

Open ID vs OAuth / Open ID 프로토콜의 흐름도

Open ID프로토콜을 통해 인증이 완료되면,  ID Token이 발급된다. 

ID Token은 JWT 형식으로 구성된 최종사용자(End-user)의 인증 정보를 담고 있는 보안 토큰이다. ID Token의 주요 claim으로는 [iss], [sub], [aud], [exp], [iat]들로 구성되어 있다.

  • iss _ ID Token을 발급한 ID Provider를 말한다(예를 들어, 구글/카카오/페이스북..)
  • sub _ Client 측에서 End-user를 식별할 수 있는 고유한 식별자를 말한다
  • aud _ ID Token이 어떤 Client를 위해 발급된 것인지를 나타낸다.
  • exp _ 만료시점, iat _ 발급시점 

> 왜 ID Token으로 Authentication을 해줘야 할까?

위키백과에서 Open ID와 OAuth에 대해 설명할 때, OAuth로 인증하는 과정을 pseudo-authentication으로 칭하며, OAuth를 Authentication 수단으로 사용할 시에 보안 결함이 발생할 수 있다고 설명한다. 

 

공부를 하면서 추가적으로 ID Token과 Access Token에 대해서 비교하는 글을 많이 보았고, 심지어 나도 정리하면서 두 개념 사이에서 헷갈린다는 생각이 많이 들었기 때문에 이에 대해서 다음 포스트에 더 정리할 예정이다.

  • 출처

https://mangkyu.tistory.com/76
https://ko.wikipedia.org/wiki/OAuth
https://velog.io/@jakeseo_me/Oauth-2.0%EA%B3%BC-OpenID-Connect-%ED%94%84%EB%A1%9C%ED%86%A0%EC%BD%9C-%EC%A0%95%EB%A6%AC
https://6991httam.medium.com/oauth%EB%9E%80-%EA%B7%B8%EB%A6%AC%EA%B3%A0-openid-8c46a65616e6
https://velog.io/@piecemaker/OAuth2-%EC%9D%B8%EC%A6%9D-%EB%B0%A9%EC%8B%9D%EC%97%90-%EB%8C%80%ED%95%B4-%EC%95%8C%EC%95%84%EB%B3%B4%EC%9E%90
https://nordicapis.com/what-is-openid-connect/