본문 바로가기

Spring Boot

인가/권한 관리 : 세션/토큰 기반 인증에서의 인가 구현

인가?

 - 세션 기반 인증에서 권한 정보가 어떻게 저장되고 활용되는가?

 - 토큰 기반 인증(JWT)에서 권한 정보가 포함되는 방식

 - 세션과 토큰 기반 인가 구현의 장단점

 - 권한 정보를 안전하게 관리하는 방법

 - 실무에서 발생할 수 있는 문제들

 

세션 기반 인가 구현

1. 세션에 권한 정보 저장

세션 기반 인증에서는 사용자가 로그인하면 서버는 세션 객체(Session Object)를 생성함.

이 객체 안에는 사용자 정보와 함께 권한(Role, Permission) 정보도 함께 저장할 수 있음

 - 서버 메모리 또는 Redis와 같은 세션 저장소에 보관하기

 - 클라이언트는 JESSIONID와 같은 세션 ID 쿠키만 전달하기

 - 서버는 세션 ID를 바탕으로 사용자와 권한 정보를 복원하기

 

세션 저장 구조 예시

SessionStore

 - sessionId: abc123

  - userId: alice

  - roles: ["USER", "EDITOR"]

  - lastAccessTime: 로컬타임 등등..

 

세션 저장 구조 예시

 

안보이면 클릭할 것

 

2. 예제

public class PostService { // HttpSession을 활용한 권한 확인 예시
	// session, post, newContent 를 받음
	public void updatePost(HttpSession session, Post post, String newContent) {
    	User user = (User)session.getAttribute("user");
        if(!post.getAuthorId().equals(user.getId()) && !user.getRoles().contains("ADMIN")) {
        	throw new SecurityException("수정 권한 없음!");
        }
        post.setContent(newContent);
    }
}

 

세션에 저장된 사용자 정보에서 권한을 조회하고 검증하는 로직..임

 

* 세션은 서버 자원을 소모하므로 확장성(Scalability)이 떨어질 수 있음

* 세션 저장소를 외부 캐시 서버(Redis, Memcached)로 구성하면 확장성 문제를 완화할 수 있음

* 세션이 만료되면 자동으로 권한도 무효화 되어야함

 

 

 

토큰 기반 인가 구현(JWT)

1. JWT에 권한 정보 포함

JWT(JSON Web Token)는 인증 정보를 클라이언트가 직접 보관하는 방식임.

서버는 JWT를 검증하기만 하면 되니까 확장성이 높다.

JWT 구조는 Header.Payload.Signature로 이루어져 있으며, Payload에 권한 정보(roles)를 포함시킬 수 있음

{ # 대충 토큰의 형태
  "Sub": "alice",
  "roles": ["USER", "EDITOR"],
  "iat": 1737072000,
  "exp": 1737075600
}

 

2. 예제(JWT 기반)

public class JwtAuthorizationService { // JWT Payload에서 권한 정보 추출 후 검증하기
	public void authorize(String jwtToken, Post post, String newContent) {
    	Claims claims = JwtUtils.parseToken(jwtToken); // Claims 타입으로 권한 정보 추출하기?
        String userId = claims.getSubject();
        List<String> roles = claims.get("roles", List.class);
        
        if(!post.getAuthorId().equals(userId) && !roles.contains("ADMIN")) {
        	throw new SecurityException("수정 권한 없음!");
        }
        post.setContent(newContent); // 검증 완료된거
    }
}

 

서버는 토큰을 해석해서 권한을 확인하고, 별도의 세션 저장소를 사용하지 않음.

세션 기반 예제와의 차이점은 HttpSession 타입의 session을 불러오지 않는다는 점

 

3. JWT 동작 흐름 다이어그램

 

JWT 동작 흐름 다이어그램, 검증만 해준다

 

* JWT는 탈취되면 만료 전까지 무효화할 방법이 없기 때문에 짧은 만료시간을 두고 Refresh Token과 함께 사용해야함

* Payload는 Base64로 인코딩된 것이기 때문에 누구나 내용을 볼 수 있다. 따라서 민감한 정보는 절대 넣지 않기!

* 서버는 무상태(Stateless) 구조를 유지할 수 있어서, 대규모 서비스에 적합하다고 함

 

 

권한 정보 관리의 모범 사례

1. 최소 권한 원칙(Principle of Least Privilege)

 - 사용자가 업무 수행에 꼭 필요한 최소한의 권한만 가지도록 설계해야함

 - 일반 사용자는 자기 글만 수정 가능, 관리자는 모든 글 수정 가능 이런식으로..

 

2. 중앙 집중 관리

 - 권한 정책은 코드 여러곳에 흩어지지 않고, 중앙 관리 모듈을 통해 관리해야함

 - AuthorizationService와 같은 클래스에서 모든 권한 검증을 수행하게끔 해야함

 

3. 로그와 모니터링

 - 권한 검증 실패는 보안 이벤트로 기록해야함

 - 관리자 페이지 접근 시 권한 부족으로 거절 - > 보안 로그에 남기기

 

4. 계층적 권한 설계

 - USER < EDITOR < ADMIN과 같이 계층적 구조를 도입하면 권한 관리가 단순해짐

 - 권한 설계를 초기에 잘못하면 유지보수가 어려워질 수 있음

'Spring Boot' 카테고리의 다른 글

OAuth : 주체와 설정  (0) 2025.10.15
OAuth : OAuth?  (0) 2025.10.13
인가/권한 관리 : 인가 구현 예시  (0) 2025.10.12
인가/권한 관리 : 권한 기반 접근 제어  (0) 2025.10.05
인가와 권한 관리 : 인가(Authorization)  (1) 2025.10.04