13. 인증 및 권한 부여[Spring Boot]

JuJaeng2·2024년 1월 13일

애플리케이션을 개발하다 보면 인증과 인가 등의 보안 기능을 추가해야할 때가 있다. 이번에는 스프링에 적용할 때 사용하는 Spring Security에 대해 알아보도록 한다.

Spring Security에 대해서 들어가기 전 보안 용어에 대해서 간단하게 알고 가보려한다.

인증(Authentication)

  • 사용자가 누구인지 확인하는 단계이다.
  • 로그인할 때 입력한 아이디와 비밀번호를 데이터베이스에 등록된 아이디와 비밀번호와 일치하는지 확인하는 과정이다.
  • 로그인에 성공하면 토큰을 발급 받고 그렇지 못하면 리소스에 접근할 수없다.

인가(Authorization)

  • 인증을 통해 검증된 사용자가 애플리케이션 내부의 리소스에 접근할 때 사용자가 해당 리소스에 접근할 권리가 있는지를 확읺는 과정을 말한다.

접근 주체(Principal)

  • 애플리케이션의 기능을 사용하는 주체를 의미한다.
  • 접근 주체는 사용자가 될 수도 있고, 디바이스, 시스템 등이 될 수도 있다.

✅ 스프링 시큐리티(Spring Security)

스프링 시큐리티는 애플리케이션의 인증, 인가 등의 보안 기능을 제공한다.
보안과 관련된 많은 기능을 제공하기 때문에 스프링 시큐리티를 활용하면 더욱 편리하게 원하는 기능을 설계할 수 있다.

✅ 스프링 시큐리티의 동작 구조

스프링 시큐리티는 Servlet Filter를 기반으로 동작한다.

Servlet Filter

  • http 요청, 응답을 조작
  • Filter Chain을 통해 여러 필터를 연결하고 사용
  • 요청과 응답을 가로채고 가공할 수 있음

필터체인(Filter Chain)은 서블릿 컨테이너에서 관리하는 ApplicationFilterChain을 의미한다. 클라이언트에서 애플리케이션으로 요청을 보매념 서블릿 컨테이너는 URI를 확인해서 필터와 서블릿을 매핑한다. 이때 스프링 시큐리티는 사용하고자 하는 필터체인을 서블릿 컨테이너의 필터 사이에서 동작시키기 위해 DelegatingFilterProxy를 사용한다.

DelegatingFilterProxy는 필터를 위한 프록시이다. 주로 Spring Security와 같은 보안 관련 구성에서 사용된다.
FilterChainProxysms 스프링 시큐리티에서 제공하는 보안 필터체인 (SecurityFilterChain)을 통해 많은 보안 필터(Security Filter)를 사용할 수 있다.

보안 필터체인은 WebSecurityConfigurerAdapter 클래스를 상속받아 설정할 수 있다. 이때 여러 보안 필터체인을 만들기 위해서는 WebSecurityConfigurerAdapter 클래스를 상속받는 클래스를 여러개 생성하면 된다.

별도의 설정이 없다면 스프링 시큐리티에서는 SecurityFilterChain에서 사용하는 필터 중 UsernamePasswordAuthenticationFilter를 통해 인증을 처리한다.

✅ JWT

JWT(Json Web Token)는 클라이언트 정보를 JSON 형태로 안전하게 전송하기 위한 토큰이다.
JWT는 URL로 이용할 수 있는 문자열로 구성돼 있고, 디지털 서명이 적용돼 있어 신뢰할 수 있다. JWT는 주로 서버와의 통신에 권한 인가를 위해 사용된다.

구조

JWT는 점(" . ")으로 구분된 세 부분으로 구성된다.

  • 헤더(Header)
  • 내용(Payload)
  • 서명(Signature)

=> "XXXXX.YYYYY.ZZZZZ" 이런 형식을 가진다.

헤더(Header)

JWT의 헤더는 검증과 관련된 내용을 담고 있다.

  • alg : 헤싱 알고리즘을 정한다.
  • type : 토큰의 타입

이렇게 두가지 속성을 가진다.

예)

{
  "alg": "HS256",
  "typ": "JWT"
}

내용(Payload)

JWT의 내용(Payload)에는 토큰에 담는 정보를 포함한다. 클레임(Claim)이라는 속성을 포함하는데 이는 세가지로 분류된다.

  • 등록된 클레임(Registered Claims)
  • 공개 클레임(Public Claims)
  • 비공개 클레임(Private Claims)

등록된 클레임

필수는 아니지만 토큰에 대한 정보를 담기 위해 이미 이름이 정해져 있는 클레임이다.

  • iss : JWT의 발급자(issuer) 주체를 나타낸다.
  • sub : JWT의 제목(Subject)를 의미한다.
  • aud : JWT의 수신인(Audience)를 의미한다.
  • exp : JWT의 만료시간(Expiration)을 의미한다.
  • iat : JWT가 발급된 시간(Issued At)을 의미한다.
  • jti : JWT의 식별자(JWT ID)를 의미한다.

공개 클레임

키 값을 마음대로 정의할 수 있다. 다만 충돌이 발생하지 않을 이름으로 설정해야 한다.

비공개 클레임

통신 간에 상호 합의되고 등록된 클레임과 공개된 클레임이 아닌 클레임을 의미한다.

서명(Signature)

서명 부분은 인코딩된 헤더, 인코딩된 내용, 비밀키, 헤더의 알고리즘 속성값을 가져와 생성된다.

😁 마무리

마지막 챕터인 인증, 인가와 관련된 스프링 시큐리티까지 완료했다. 이번에는 책을 읽으며 프로젝트에 바로 적용할 필요가 있어 바로 적용을 하며 공부를 했다. 평소에 회원가입 처리는 동일한 값이 없다면 회원가입이 가능하도록 처리했고, 로그인은 아이디와 비밀번호가 존재하고 일치한다면 로그인가능하도록 처리하는것에 그쳤었다. 하지만 스프링 시큐리티와 JWT를 학습하므로 토큰과 시큐리티를 통해 인증, 인가 기능을 구현할 수 있게 되었다. 정확한 구조를 알고싶어 책의 내용을 최대한 자세히 읽어보았지만 큰틀만 이해하고 조금 더 세부적이 내용은 이해하기 아직은 힘들었다. 항상 로그인과 회원가입은 어떻게 처리를 하는지 궁금했는데 이번 시간에 궁금증이 많이 해소되어서 기분은 좋았다.

항상 느끼지만 아는 만큼 보이는것 같다. 무엇이든 그때 그 상황이 최선이라고 생각했는데 이번 북스터디를 통해 내가 알지 못하는 수많은 기술들이 존재한다는 것을 직접 느낄 수 있어서 좋은 기회였다고 생각한다. 지금도 책의 내용을 학습하는 것에서 그쳤다고 생각한다. 아직은 내 기준 가장 좋은 기술들이지만 분명 프로젝트를 진행하며 공부하다보면 이 이상의 무언가가 있을것이라고 생각한다.
항상 새로운것을 받아들이는 마음으로 개발에 임한다면 나의 성정에도 플러스고 개발중인 애플리케이션에도 플러스 요인이 될것이라고 생각한다.

profile
다 잘하고 싶은 개발자

0개의 댓글