728x90
Authorization
당신에게 무엇이 허가 되었는지 증명하는 것

스프링 시큐리티가 지원하는 권한 계층
-
웹 계층
-
URL 요청에 따른 메뉴 혹은 화면 단위의 레벨 보안

-
-
서비스 계층
-
화면 단위가 아닌 메소드 같은 기능 단위의 레벨 보안

-
-
도메인 계층(Access Control List, 접근제어 목록)
-
객체 단위의 레벨 보안

-
FilterSecurityInterceptor
- 마지막에 위치한 필터로써 인증된 사용자에 대하여 특정 요청의 승인/거부 여부를 최종적으로 결정
- 인증 객체 없이 보호자원에 접근을 시도할 경우 AuthenticationException을 발생
- 인증 후 자원에 접근 가능한 권한이 존재하지 않을 경우 AccessDeniedException을 발생
- 권한 제어 방식 중 HTTP 자원의 보안을 처리하는 필터
- 권한 처리를 AccessDecisionManager에게 맡김

동작 흐름
- 인증 객체 있는지 체크 (없으면 AuthenticationException 예외를 발생시킨다)
- SecurityMetadataSource가 사용자의 인증 객체를 권한 정보를 가지고 온다.
- 권한 정보가 null : 자원 접근 허용
- null 아님 : AccessDecisionManager가 권한 정보를 받아 AccessDecisionVoter 심의 요청을 한다.
- 접근이 승인이 될 경우 자원 접근을 허용하고, 승인이 실패할 경우 AccessDeniedException 예외가 발생한다.
-
protected InterceptorStatusToken beforeInvocation(Object object) { Assert.notNull(object, "Object was null"); if (!getSecureObjectClass().isAssignableFrom(object.getClass())) { throw new IllegalArgumentException("Security invocation attempted for object " + object.getClass().getName() + " but AbstractSecurityInterceptor only configured to support secure objects of type: " + getSecureObjectClass()); } //자원에 설정된 권한을 가지고 오는 부분 Collection<ConfigAttribute> attributes = this.obtainSecurityMetadataSource().getAttributes(object); if (CollectionUtils.isEmpty(attributes)) { Assert.isTrue(!this.rejectPublicInvocations, () -> "Secure object invocation " + object + " was denied as public invocations are not allowed via this interceptor. " + "This indicates a configuration error because the " + "rejectPublicInvocations property is set to 'true'"); if (this.logger.isDebugEnabled()) { this.logger.debug(LogMessage.format("Authorized public object %s", object)); } publishEvent(new PublicInvocationEvent(object)); return null; // no further work post-invocation } // 그 사용자가 인증객체가 있는지 없는지 if (SecurityContextHolder.getContext().getAuthentication() == null) { credentialsNotFound(this.messages.getMessage("AbstractSecurityInterceptor.authenticationNotFound", "An Authentication object was not found in the SecurityContext"), object, attributes); } Authentication authenticated = authenticateIfRequired(); if (this.logger.isTraceEnabled()) { this.logger.trace(LogMessage.format("Authorizing %s with attributes %s", object, attributes)); } // Attempt authorization attemptAuthorization(object, attributes, authenticated); if (this.logger.isDebugEnabled()) { this.logger.debug(LogMessage.format("Authorized %s with attributes %s", object, attributes)); } if (this.publishAuthorizationSuccess) { publishEvent(new AuthorizedEvent(object, attributes, authenticated)); } // Attempt to run as a different user Authentication runAs = this.runAsManager.buildRunAs(authenticated, object, attributes); if (runAs != null) { SecurityContext origCtx = SecurityContextHolder.getContext(); SecurityContext newCtx = SecurityContextHolder.createEmptyContext(); newCtx.setAuthentication(runAs); SecurityContextHolder.setContext(newCtx); if (this.logger.isDebugEnabled()) { this.logger.debug(LogMessage.format("Switched to RunAs authentication %s", runAs)); } // need to revert to token.Authenticated post-invocation return new InterceptorStatusToken(origCtx, true, attributes, object); } this.logger.trace("Did not switch RunAs authentication since RunAsManager returned null"); // no further work post-invocation return new InterceptorStatusToken(SecurityContextHolder.getContext(), false, attributes, object); }
728x90
'스프링 시큐리티' 카테고리의 다른 글
| Ch02. 스프링 시큐리티 주요 아키텍처 이해 - 스프링 시큐리티 필터 및 아키텍처 정리 (0) | 2022.01.17 |
|---|---|
| Ch02. 스프링 시큐리티 주요 아키텍처 이해 - 인가 결정 심의자(AccessDecisionManager, AccessDecisionVoter) (0) | 2022.01.17 |
| Ch02. 스프링 시큐리티 주요 아키텍처 이해 - 인증 처리자(AuthenticationProvider) (0) | 2022.01.17 |
| Ch02. 스프링 시큐리티 주요 아키텍처 이해 - 인증 관리자(AuthenticationManager) (0) | 2022.01.17 |
| Ch02. 스프링 시큐리티 주요 아키텍처 이해 - 인증 흐름 이해(Authentication Flow) (0) | 2022.01.16 |