Search
Duplicate

실전프로젝트 - 인가 프로세스 DB연동 웹 계층 구현

스프링 시큐리티 인가 개요

DB와 연동하여 자원 및 권한을 설정하고 제어함으로 동적 권한 관리가 가능하도록 한다.
설정 클래스 소스에서 권한 관련 코드 모두 제거
ex) antMatcher("/user").hasRole("USER")
관리자 시스템 구축
회원 관리 - 권한 부여
권한 관리 - 권한 생성, 삭제
자원 관리 - 자원 생성, 삭제, 수정, 권한 매핑
권한 계층 구현
URL - Url 요청 시 인가처리
Method - 메소드 호출 시 인가 처리
Method
Pointcut

관리자 시스템- 권한 도메인, 서비스, 리포지토리구성

Git 참고하면되지만, 사실상 의미없음. 예제가 너무 불친절.

웹 기반 인가처리 DB 연동- 주요 아키텍처 이해

1. 스프링 시큐리티의 인가처리

http.antmatchers("/user").access("hasRole('USER')")
사용자(인증정보)/user 자원(요청정보)에 접근하기 위해서는 ROLE_USER 권한(권한정보)이 필요하다
인증정보(Authentication)은 SecurityContext에서 얻는다.
요청정보는 FilterInvocation클래스를 생성해서 request 정보를 얻는다.
권한정보는 설정클래스에서 설정한 내용(ex: hasRole('USER'))을 파싱해서 얻어낸다.
→ 내부적으로 스프링 시큐리티가 초기화 될 때 설정했던 내용들(ex: http.antmatchers("/user").access("hasRole('USER')")) 에서 자원정보와 권한정보를 꺼내어 Map객체에 key(자원정보), value(권한정보)를 저장합니다.
⇒ 사용자가 자원요청을 할 경우 보안필터(SecurityInterceptor)가 요청을 받은 뒤 인증, 요청, 권한 정보들을 얻어서 접근 결정 관리자(AccessDecisionManager)에게 전달합니다.

2. 대략적인 Code상 권한정보 파싱및 저장 로직(초기화)

파싱된 결과들(List<Map>)이 저장되는 곳은 ExpressionBasedFilterInvocationSecurityMetadataSourcerequestToExpressionAttributesMap이다.
부모객체(DefaultFilterInvocationSecurityMetadataSource)에 먼저 map객체를 전달해서 설정정보들을 가지고 있게 합니다.
이로써 DefaultFilterInvocationSecurityMetadataSourcerequestMap에 설정정보들을 담고 있게 됩니다.

2. 두가지 방법의 권한 추출 방법

자원의 설정된 권한 정보를 추출하도록 구현
getAttributes(Object object)를 override해서 실질적인 구현을 한다.
Method방식의 권한 정보 추출은 이미 구현되있는 클래스를 활용하여 Annotation방식으로 인가처리 설정을 해주도록 한다.
@RolesAllowed, @Secured, @PreAuthorize, @PostAuthorize

3. Flow

웹 기반 인가처리 DB 연동 -FilterInvocationSecurityMetadataSource(1)

사용자가 접근하고자 하는 Url 자원에 대한 권한 정보 추출
AccessDecisionManager 에게 전달하여 인가처리 수행
DB로부터 자원 및 권한 정보를 매핑하여 맵으로 관리
사용자의 매 요청마다 요청정보에 매핑된 권한 정보 확인

Flow

1.
사용자는 /admin 으로 접근
2.
보안필터(FilterSecurityInterceptor)에서 권한정보 조회
3.
FilterInvocationSecurityMetadataSource에서 요청정보와 매칭되는 권한정보 추출
RequestMap 에서 요청정보(/admin) 이 key값인 data(권한 목록)를 찾는다. (DB조회)
4.
권한 목록이 존재하지 않는다면 인가처리를 하지 않는다.
5.
권한 목록이 존재한다면 AccessDecisionManager에 정보들(인증객체, 요청정보, 권한정보들)을 넘긴다.

Sequence Diagram

웹 기반 인가처리 DB 연동 -FilterInvocationSecurityMetadataSource(2)

1. Url방식 - Map 기반 DB 연동

UrlResourcesMapFactoryBean
DB로 부터 얻은 권한/자원 정보를 ResourceMap을 빈으로 생성해서 UrlFilterInvocationSecurityMetadataSource에 전달

웹 기반 인가처리 실시간 반영하기

1. Url 방식- 인가처리 실시간 반영하기

인가처리 허용 필터 - PermitAllFilter 구현

1. Url 방식 -PermitAllFilter 구현

인증 및 권한심사를 할 필요가 없는 자원(ex: /, /home, /login) 들을 미리 설정해서 바로 리소스 접근이 가능하게 하는 필터

1. security / filter / PermitAllFilter

Code

2. security / configs / SecurityConfig 설정 등록

Code

계층 권한 적용하기 RoleHierachy

Url 방식 - 계층 권한 적용하기

→ 기존 의 ROLE을 보면 ADMIN 과 USER가 있지만 ADMIN은 USER의 상위 계층이 아니고 그냥 이름이 다른 하나의 ROLE일 뿐이다. 하지만 그렇게만 적용해서는 ROLE마다 권한을 하나하나 각각 줘야하는 문제가 있다. 그렇기에 계층을 적용해서 윗 계층은 아래계층의 권한을 포함하도록 해야 한다.

RoleHirearchy

상위 계층 Role은 하위 계층 Role의 자원에 접근 가능함.
Role_ADMIN > ROLE_MANAGER > ROLE_USER 일 경우 ROLE_ADMIN 만 있으면 하위 ROLE의 권한을 모두 포함한다.

RoleHierarchyVoter

RoleHierarchy 를 생성자로 받으며 이 클래스에서 설정한 규칙이 적용되어 심사함.

1. service / RoleHierarchyService, service/ impl / RoleHierarchyServiceImpl

Code

2. security / init / SecurityInitializer

Code

3. security / configs / SecurityConfig 설정 등록및 변경

Code

아이피 접속 제한하기 - CustomIpAddressVoter

Url 방식 - 아이피 접속 제한하기

심의 기준

특정한 IP만 접근 가능하도록 심의하는 Voter 추가
Voter 중에서 가장 먼저 심사하도록 하여 허용된 IP일 경우에만 최종 승인 및 거부 결정을 하도록 한다.
허용된 IP이면 ACCESS_GRANTED 가 아닌 ACCESS_ABSTAIN 을 리턴해서 추가 심의를 계속 진행하도록 한다.
허용된 IP가 아니면 ACCESS_DENIED를 리턴하지 않고 즉시 예외 발생하여 최종 자원 접근 거부

1. domain / entity / AccessIp

Code

2. repository / AccessIpRepository

Code

3. service / SecurityResourceService 수정및 메서드 추가

Code

4. security/ voter / IpAddressVoter

Code

5. security / configs / SecurityConfig 설정 등록

Code