> Hello World !!!

     

@syaku

Spring Security OAuth with JWT

https://github.com/syakuis/spring-security-oauth

코드를 함께 보면서 작업하시면 도움이 됩니다.

목차

시작하며

Spring security oauth 프로젝트를 사용하여 Authorization Server와 Resource Server를 OAuth 2.0 workflow 기반으로 개발한다.

OAuth 2.0은 자사의 서비스를 제 3자에게 제공하기 위해 기존 세션방식으로는 한계가 있었기에 이를 해결하고자 새로운 인증 방식을 구상하였고 기업마다 다른 인증 방식으로 무분별하게 만들게 되면서 이를 표준화하기 위해 정의한 것이 OAuth 2.0이다.

참고사항

Spring Security 팀에서 Spring Security OAuth 프로젝트를 세부적으로 분리하기로 결정하였다. Authorization Server는 새로운 프로젝트로 분리되고 Resource Server는 기존처럼 Spring Security에 포함한다고 발표했다. 자세한 내용은 아래 링크를 참고할 수 있다.

https://github.com/spring-projects/spring-security/wiki/OAuth-2.0-Migration-Guide

Spring Security OAuth 2.5.1.RELEASE는 레거시의 마지막 버전이 될 것 같다. 이미 Authorization Server 관련 클래스는 Deprecated 이다.

참고: Spring Security OAuth 2 개발자 가이드

Docs: https://docs.spring.io/spring-security-oauth2-boot/docs/2.2.x-SNAPSHOT/reference/html/index.html

레거시 버전을 사용하는 것은 문제가 되지 않지만 앞으로 지원이 없을 것으로 예상된다. 차세대 버전을 사용하는 것을 고려해야 한다.

차세대 버전에 대한 정보는 https://github.com/spring-projects/spring-authorization-server 참고한다.

내용이 많아 각 목차별로 페이지를 나눴고 해당 목차만 필요한 경우도 있어서 가독성을 높이기 위해 페이지를 세부적으로 분리하였다.

용어 정리

  • Authorization Server - 인증과 인가를 모두 처리하는 서버이다. 인증은 사용자에게 입장권을 발급하는 것이고 인가는 입장권으로 특정 장소에 입장할 수 있는 권한을 얻는 것이다. 이 명칭은 OAuth 2.0 표준에서 사용하는 용어이다.
  • Resource Server - 사용자가 입장하려는 특정한 장소이다. 즉 REST API를 구현한 서버이거나 정보를 제공하는 자원 서버이다. 자원 서버는 인증된 사용자만 허용하기 위해 인증 서버와 연동하여 인증된 사용자 정보를 얻을 수 있다. 누구나 접속할 수 있고 사용자 정보가 필요하지 않다면 인증 서버와 연동할 필요는 없다.
  • JWT - 일반적인 OAuth 2.0 액세스 토큰은 인증 코드만 존재한다. 액세스 토큰으로 사용자 정보를 얻는 부분에서 트래픽이 발생되며 서비스간에 의존성이 생기는 부분을 해결하고자 액세스 토큰 자체에 사용자 정보와 같은 부가 정보를 추가한 토큰이 JWT이다. JWT 자체만으로 인증된 것으로 판단될 수 있다.
  • Client Registation - 인증 서버를 사용하기 위해 대상이 되는 애플리케이션을 등록하고 관리하는 서비스이다. 애플리케이션은 ClientId와 ClientSecret을 얻어야 인증 서버를 사용할 수 있다. 등록된 애플리케이션에 대해 access token 만료시간과 사용 범위 그리고 refresh token 사용 여부 등을 정의할 수 있다.

OAuth 2.0 이해하기

인증 서버를 개발하기 위해 꼭 알고 있으면 좋을 내용을 정리하였다. 아래 링크를 참고한다.

OAuth 2.0 Simplified

Authorization Server 개발

Authorization Server 개발은 spring security oauth 2.5.1.RELEASE 버전으로 개발하였다.

추후 차세대 버전으로 추가 가이드를 할 예정이다.

인증 서버 준비

Spring Security OAuth - Authorization Server

인증 방식은 총 4가지를 제공하며 각각 인증 방식에 대해 알아본다.

Password

Spring Security OAuth - Password 인증 방식

Authorization Code

Spring Security OAuth - Authorization Code 인증 방식

Implicit

자바스크립트로 구현된 SPA에서 액세스 토큰을 교활할때 사용한다. 브라우저는 기밀 정보를 안전하게 저장할 수 없어 Authorization Code 인증 방식에서 code를 응답받는 부분이 제외되고 바로 액세스 토큰이 발급된다.

응답시 액세스 토큰은 redirect url 로 요청되며 관련 값들은 parameter에 담아서 전달된다.

본 인증 방식은 보안이 취약할 수 있어 사용을 권장하지 않는 다.

Client Credentials

Spring Security OAuth - Client Credentials 인증 방식

인증 방식 응답 전문

응답 전문은 Implicit 인증 방식을 제외하고 대부분 유사하며 Client Credentials 는 사용자 정보는 포함되지 않는 다.

POST http://localhost:8080/oauth/token?grant_type=password&username=test&password=1234

HTTP/1.1 200 OK
Cache-Control: no-store
X-XSS-Protection: 1; mode=block
Pragma: no-cache
X-Frame-Options: DENY
Date: Tue, 02 Nov 2021 02:30:37 GMT
Connection: keep-alive
X-Content-Type-Options: nosniff
Transfer-Encoding: chunked
Content-Type: application/json;charset=UTF-8

{
  "access_token": "eyJhbGciOi...9pTicJ_Pqt018O_oA",
  "token_type": "bearer",
  "refresh_token": "eyJhbGciOiJSUzI1NiIsIn...JjfrrA",
  "expires_in": 5999,
  "scope": "read",
  "uid": "c7b782b5-f8b5-11eb-972f-02a208506bd6",
  "additionalInformation": null,
  "name": "테스트",
  "jti": "834ad8a9-5aa1-4fcd-8034-f6133a106700"
}
  • access_token - JWT 기반의 액세스 토큰이다. 해당 토큰으로 만료될때까지 인증된 상태라고 할 수 있다.
  • refresh_token - access_token 이 만료될때 인증 방식으로 다시 인증을 받지 않고 refresh_token으로 access_token을 새로 발급 받을 수 있다. 하여 refresh_token의 만료시간은 access_token 만료시간보다 늦어야 한다.
  • token_type - 토큰 형식을 설정한다. 기본적으로 beare 이다.
  • expires_in - 액세스 토큰 만료 시간이다.
  • scope - 액세스 토큰에 대한 접근 권한 범위이다.
  • jit - JWT의 고유 id 이다.
  • 그외 커스텀 항목 - uid, name, additionalInformation

JWT Payload 정보는 서버간의 통신시 헤더에 담아 전달되는 정보로 일반화된 정보로 간소화하는 것이 효율적이다.

응답 전문에 액세스 토큰의 JWT 정보를 프론트엔드나 클라이언트 프로그램에서 사용하는 것은 기밀성을 보장할 수 없므로 안전하다 볼 수 없다. JWT 정보는 서버에서만 사용할 수 있도록 설계해야 한다. 이부분에 대해 추후 다시 설명하도록 한다.

인증 응답 오류

  • 인증 방식에서 발생되는 오류는 body가 아닌 header 에 담겨서 전달된다.
  • 오류 로그를 확인하려면 org.springframework.security: trace 레벨을 사용해야 한다.

Resource Server 개발

Spring Security OAuth - Resource Server

참고 자료

부가적으로 읽을 거리