ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Spring Security] Authentication과 Authorization
    Spring/Spring Security 2022. 1. 22. 17:35

    Authentication(인증)과 Authorization(인가)

    출처 https://ivorycode.tistory.com/entry/%EC%9D%B8%EC%A6%9DAuthentication%EA%B3%BC-%EC%9D%B8%EA%B0%80Authorization

    Authentication(인증)이란 ?

    식별 가능한 정보를 이용하여 서비스에 등록된 유저인지를 파악하기 위한 과정이다.

    즉 인증을 통해 등록된 사용자에게만 서비스를 제공한다.

    Authorization(인가)이란 ?

    인증된 사용자가 접근하려는 자원에 대한 권한이 있는지 확인하는 과정이다.

    인가에 앞서 인증이 반드시 선행되어야 한다.

    Authentication(인증) 방식

    인증 방식에는 크게 세션 기반 인증 방식, 토큰기반 인증 방식, OAuth 기반 인증 방식이 있다.

    (OAuth 기반 인증 방식은 다음 포스트에서 다룰 예정)

     

    Session(세션) 기반 인증 방식

    세션 기반 인증 방식의 핵심은 사용자의 정보를 세션 스토리지에 저장해 서버에서 관리한다는 것이다.

    Session 이란 ?

    세션이란 일정 시간 동안 같은 사용자(브라우저)로부터 들어오는 일련의 요청을 하나의 상태로 보고 그 상태를 일정하게 유지시키는 기술을 말한다. 또한, 여기서 일정 시간이란 방문자가 웹 브라우저를 통해 웹 서버에 접속한 시점으로부터 웹 브라우저를 종료함으로써 연결을 끝내는 시점을 말한다. 즉, 방문자가 웹서버에 접속해 있는 상태를 하나의 단위로 보고 세션이라고 칭한다.

    Cookie 란 ?

    특정 웹 사이트를 방문했을 때 만들어지는 정보를 담는 파일을 말하며, 쉽게 말해 상태 정보를 유지하는 기술이다.

    동작 방식

     

    출처 https://k3068.tistory.com/88#spring%25--security%25--%EC%25--%25--%EC%25--%25-C%EB%25-A%25--%25--%EA%25B-%25B-%EB%25B-%25B-%EC%25A-%25--%EC%25-C%BC%EB%25A-%25-C%25--%EC%25--%25B-%EC%25--%25--%25---%25--%EC%BF%25A-%ED%25--%25A-%25--%EB%25B-%25A-%EC%25-B%25-D%EC%25-D%25--%25--%EC%25--%AC%EC%25-A%25A-%ED%25--%25--%EA%25B-%25A-%25--%EC%25-E%25--%EB%25-B%25A--

    1. 클라이언트가 서버로 로그인 요청을 보낸다.
    2. 서버는 클라이언트가 보낸 사용자 정보(ID, PW)를 확인한다.
    3. 사용자 정보가 유효하면 세션을 생성하고,
    4. 세션 ID를 발급해
    5. 쿠키에 담아 요청에 대한 응답을 한다.
    6. 클라이언트는 인증이 필요한 요청을 할 때마다 헤더에 쿠키 포함해 보낸다.
    7. 서버는 쿠키를 검증하고,
    8. 사용자 인증이 완료되면 사용자 정보를 가져와
    9. 요청에 대한 응답을 한다.

    장점

    보안

    • 쿠키가 포함된 요청이 외부에 노출되어도 쿠키(세션 ID)는 유의미한 값을 갖고 있지 않기 때문에 큰 문제를 일으키지 않는다.

    세션 저장

    • 서버에서 클라이언트의 세션 정보를 메모리나 DB 등의 스토리지에 저장하고 있으므로, 사용자의 로그인 여부 확인이 용이하고, 경우에 따라서 강제 로그아웃 등의 제재를 가할 수 있다.

    단점

    보안

    • 쿠키 노출 자체는 문제가 없지만 해커가 HTTP 요청을 가로챈다면(세션 하이재킹), 해당 쿠키로 서버에 부적절한 HTTP 요청을 보낼 수 있다.
      • 이를 방지하기 위해 세션의 유효시간을 짧게 가져가거나(궁극적인 해결책은 아님) HTTPS를 사용해 메시지를 암호화하는 방법을 사용해야 함.

    세션 저장

    • 서버에서 클라이언트의 상태를 모두 유지하고 있어야 하므로, 사용자가 많아질 경우 스토리지 부하가 심하다.

    확장성

    • 중앙 세션 저장소에서 세션을 관리하지 않으면 서버 확장에 어려움이 있다.
      • 클라이언트마다 배정되는 서버가 달라질 수 있기 때문에 배정된 서버에 해당 사용자의 정보가 존재하지 않을 수 있음 
      • 중앙 세션 저장소에 장애가 발생하면 시스템 전체에 문제가 될 수 있음(Single Point of Failure)

     

    토큰 기반 인증 방식

    토큰 기반 인증 중에 가장 많이 사용하고 있는 JWT 기반 인증 방식에 대해 알아보자.

    JWT란 ?

    JWT(Json Web Token)란 Json 포맷을 이용하여 사용자 속성 정보를 저장하는 Claim 기반의 Web Token이다. JWT는 토큰 자체를 정보로 사용하는 Self-Contained 방식으로 정보를 안전하게 전달한다. JWT 기반 인증 방식을 사용할 경우 클라이언트는 HTTP request header에 JWT(access token)를 포함해 요청하고 서버는 별도의 인증 과정 없이 헤더에 포함되어 있는 JWT 정보를 통해 인증한다.

    JWT 구조

    JWT는 세 파트로 나누어지며 . 을 통해 구분되고 순서대로 Header, Payload, Signature로 구성된다. 또한 Json 형태인 각 부분은 Base64로 인코딩되어 표현된다. Base64는 암호화된 문자열이 아니고, 같은 문자열에 대해 항상 같은 인코딩 문자열을 반환한다.

    출처: https://jwt.io/

    1. Header(헤더)

    출처: https://jwt.io/

    Header는 typ alg 두 가지 정보로 구성된다. 

     

    • typ: 토큰의 타입을 지정 e.g., JWT
    • alg: 알고리즘 방식을 지정하며, 서명(Signature) 및 토큰 검증에 사용 e.g., HS256(SHA256) 또는 RSA

    2. Payload(페이로드)

    출처: https://jwt.io/

    Payload에는 토큰에서 사용할 정보의 조각들인 클레임(Claim)이 담겨 있다. 클레임은 Json(Key/Value) 형태로 다수의 정보를 넣을 수 있으며, 등록된(registered) 클레임, 공개(public) 클레임, 비공개(private) 클레임으로 세 종류가 있다.

    • 등록된 클레임(Registered Claim)
      등록된 클레임은 토큰 정보를 표현하기 위해 이미 정해진 종류의 데이터들로, 모두 선택적으로 작성이 가능하며 사용할 것을 권장한다.
      • iss: 토큰 발급자(issuer)
      • sub: 토큰 제목(subject)
      • aud: 토큰 대상자(audience)
      • exp: 토큰 만료 시간(expiration), NumericDate 형식으로 되어 있어야 함 ex) 1480849147370
      • nbf: 토큰 활성 날짜(not before), 이 날이 지나기 전의 토큰은 활성화되지 않음
      • iat: 토큰 발급 시간(issued at), 토큰 발급 이후의 경과 시간을 알 수 있음
      • jti: JWT 토큰 식별자(JWT ID), 중복 방지를 위해 사용하며, 일회용 토큰(Access Token) 등에 사용

     

    • 공개 클레임(Public Claim)
      공개 클레임은 사용자 정의 클레임으로, 공개용 정보를 위해 사용된다 충돌 방지를 위해 URI 포맷을 이용한다.
      {
        "https://choiblack.tistory.com/":true
      }

     

    • 비공개 클레임(Private Claim)
      등록된 클레임도아니고, 공개된 클레임들도 아닙니다. 양 측간에 (보통 클라이언트↔서버) 협의 하에 사용되는 정보를 저장한다. 공개 클레임과 달리 이름이 중복되어 충돌될 수 있어 사용에 유의해야 한다.
      {
        "username":"choiblack"
      }

    3. Signature(서명)

    출처: https://jwt.io/

    Signature토큰을 인코딩하거나 유효성 검증을 할 때 사용하는 고유한 암호화 코드이다. 서명(Signature)은 위에서 만든 HeaderPayload의 값을 각각 BASE64로 인코딩하고, 인코딩한 값을 비밀 키를 이용해 Header에서 정의한 알고리즘으로 해싱을 하고, 이 값을 다시 BASE64로 인코딩하여 생성한다.

    Access token과 Refresh token

    access token과 refresh token 모두 사용자가 로그인을 하고 인증됐을 경우 서버에서 secret key를 사용해서 발급하는 토큰이다.

    1. access token은 클라이언트가 서버 resource를 사용하기 위한 접근용 토큰으로 만료 기간을 10~15분으로 짧게 두어 자주 발급받게 한다. 이렇게 함으로써 만약 access token이 도난당하더라도 금방 만료되어 안정성이 유지된다.
    2. refresh token은 access token이 만료됐을 때 access token을 재발급받기 위한 인증용 토큰이다. 평소의 요청에는 request에 포함되지 않으며 오직 access token을 재발급받는 용도로만 사용한다. 만료 기간은 자동 로그인 기능을 몇 달로 지정할 것인가에 따라 조절하고, 만료 기간이 끝나면 사용자에게 로그인을 다시 요청한다.

    동작 방식

     

    출처: https://k3068.tistory.com/90

    1. 클라이언트가 서버로 로그인 요청을 보낸다.
    2. 서버는 클라이언트가 보낸 사용자 정보(ID, PW)가 유효하다면, 서버에서 secret key를 사용해 토큰(access token, refresh token)을 발급한다.
    3. JWT를 클라이언트(브라우저)에게 전달하고 클라이언트의 로컬 스토리지(세션 스토리지, 쿠키)에 토큰을 저장한다.
    4. 클라이언트는 모든 request 메시지 헤더에 access token을 포함해 전송한다.
    5. 서버는 클라이언트가 보낸 access token을 검증한다.
    6. access token이 유효하다면, 해당하는 response를 한다.

    장점

    토큰 저장

    • 토큰을 클라이언트에 저장하기 때문에 서버 리소스의 부담이 없다.

    확장성

    • 어떤 서버에서든 동일한 secret key만 가지고 있으면 토큰을 검증할 수 있기 때문에 서버 확장에 용이하다.

    단점

    보안

    • 버에서 클라이언트의 상태를 저장하고 있지 않아 토큰을 무력화하기 어렵다. 따라서 악의적인 사용자는 만료 기간이 지나기 전까지 정보 탈취가 가능하다.
      • access token의 만료 기간을 최대한 짧게 해 피해를 최소화해야 한다.
    • refresh token이 도난될 경우 계속해서 access token을 발급해 악용할 가능성이 있다.
      • refresh token을 클라이언트가 아닌 서버에 저장해 access token이 만료되었을 때만 사용한다. (세션 방식과 같은 문제가 발생함)

    Payload

    • payload를 따로 암호화하지 않아 디코딩하면 누구나 정보를 확인할 수 있기 때문에 중요한 정보를 payload에 넣을 수 없다.

    토큰 길이

    • 일반적으로 payload에 필요한 정보를 저장하는 경우가 많아 토큰의 길이가 길어져 Message가 무거워질 수 있다.

     


    Reference

    https://k3068.tistory.com/88#spring%25--security%25--%EC%25--%25--%EC%25--%25-C%EB%25-A%25--%25--%EA%25B-%25B-%EB%25B-%25B-%EC%25A-%25--%EC%25-C%BC%EB%25A-%25-C%25--%EC%25--%25B-%EC%25--%25--%25---%25--%EC%BF%25A-%ED%25--%25A-%25--%EB%25B-%25A-%EC%25-B%25-D%EC%25-D%25--%25--%EC%25--%AC%EC%25-A%25A-%ED%25--%25--%EA%25B-%25A-%25--%EC%25-E%25--%EB%25-B%25A--

    https://brownbears.tistory.com/439

    https://millo-l.github.io/Session-%EA%B8%B0%EB%B0%98-%EC%9D%B8%EC%A6%9D%EB%B0%A9%EC%8B%9D/

    https://mangkyu.tistory.com/56

    https://velopert.com/2389

    댓글

Designed by Tistory.