스프링 시큐리티 인가 개요
•
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>)이 저장되는 곳은 ExpressionBasedFilterInvocationSecurityMetadataSource 의 requestToExpressionAttributesMap이다.
•
부모객체(DefaultFilterInvocationSecurityMetadataSource)에 먼저 map객체를 전달해서 설정정보들을 가지고 있게 합니다.
•
이로써 DefaultFilterInvocationSecurityMetadataSource 의 requestMap에 설정정보들을 담고 있게 됩니다.
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