티스토리 뷰

회원가입을 한다고 해서 사이트에서 모든 권한을 가입자에게 쥐어주지는 않는다.

운영자와 회원이 접근할 수 있는 사이트의 영역은 분리되어 있고 회원도 다양한 계급으로 접근할 수 있는 영역이 분리되어 있는 경우도 존재하는데  SpringSecurity에서는 해당 User가 지금 접근하려는 영역에 접근할 수 있는지 권한을 확인하고 접근할 수 있는 권한을 부여하는데 인증처리에 이어 어떻게 접근권한을 부여하는지 살펴보려고 한다.

 

흐름은 다음과 같다

 

스프링 권한부여 처리 흐름

                        출처:https://docs.spring.io/spring-security/reference/servlet/authorization/authorize-http-requests.html

 

AuthorizationFilter에서 스프링 인증처리흐름에서 abstractAuthenticationProcessingFilter에서 저장한 SecurityContextHolder에서 authentication을 가져오고 HttpServletRequest를 통해 check() 메서드를 진행한다

public class AuthorizationFilter extends OncePerRequestFilter {

	...
    
    @Override
	protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
			throws ServletException, IOException {

		AuthorizationDecision decision = this.authorizationManager.check(this::getAuthentication, request);
        //authorizationManager의 check메서드를통해 authentication의 권한을 확인한다.
		this.eventPublisher.publishAuthorizationEvent(this::getAuthentication, request, decision);
		if (decision != null && !decision.isGranted()) {
			throw new AccessDeniedException("Access Denied");
		}
		filterChain.doFilter(request, response);
	}
    
    private Authentication getAuthentication() {
		Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        //인증처리흐름에서 abstractAuthenticationProcessingFilter에서 저장했던 SecurityContextHolder에서
        //Authentication을 가져온다.
		if (authentication == null) {
			throw new AuthenticationCredentialsNotFoundException(
					"An Authentication object was not found in the SecurityContext");
		}
		return authentication;
	}
    
    ...
    
}

 

check() 메서드는 AuthorizationManager에서 선언되어져 있다.

@FunctionalInterface
public interface AuthorizationManager<T> {
	...
    
    @Nullable
	AuthorizationDecision check(Supplier<Authentication> authentication, T object);

}

이중 해당 메서드를 HttpRequest와 Authentication을 파라미터로 받는 구현클래스는 RequestMatcherDelegatingAuthorizationManager이고, 해당 메서드에서 AuthorizationManager를 순회하면서 적합한 AuthorizationManager를 찾아서 권한을 체크하게 된다.

 

public final class RequestMatcherDelegatingAuthorizationManager implements AuthorizationManager<HttpServletRequest> {

	...
    
    @Override
	public AuthorizationDecision check(Supplier<Authentication> authentication, HttpServletRequest request) {
		if (this.logger.isTraceEnabled()) {
			this.logger.trace(LogMessage.format("Authorizing %s", request));
		}
		for (RequestMatcherEntry<AuthorizationManager<RequestAuthorizationContext>> mapping : this.mappings) {
        //for문을 통해 적합한 AuthorizationManager를 탐색한다
			RequestMatcher matcher = mapping.getRequestMatcher();
			MatchResult matchResult = matcher.matcher(request);
			if (matchResult.isMatch()) {
				AuthorizationManager<RequestAuthorizationContext> manager = mapping.getEntry();
                //matchResult가 일치할 경우 AuthorizationManager 객체를 얻어서 사용자의 권한을 확인한다.
				if (this.logger.isTraceEnabled()) {
					this.logger.trace(LogMessage.format("Checking authorization on %s using %s", request, manager));
				}
				return manager.check(authentication,
						new RequestAuthorizationContext(request, matchResult.getVariables()));
			}
		}
		this.logger.trace("Abstaining since did not find matching RequestMatcher");
		return null;
	}
    
    ...
    
}

 

'공부 > 오늘의공부' 카테고리의 다른 글

스프링 시큐리티 인증 처리흐름  (0) 2023.03.16
스트림  (0) 2023.01.17
람다  (0) 2023.01.16
컬렉션 Map  (0) 2023.01.12
컬렉션 Set  (0) 2023.01.11
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/07   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
글 보관함