Spring Security 권한 부여

김병수·2022년 11월 28일
0
post-thumbnail

Spring Security 권한 부여 처리 흐름

  1. Spring Security Filter Chain에서 URL을 통해 사용자의 액세스를 제한하는 권한 부여 Filter인 AuthorizationFilter는 SecurityContextHolder로부터 Authentication을 획득한다.

  2. 획득한 Authentication과 HttpservletRequest를 AuthorizationManager에게 전달한다.

    • AuthorizationManager는 권한 부여 처리를 총괄하는 매니저 역할을 하는 인터페이스 RequestMatcherDelegationgAuthorizationManager는 AuthorizationManager를 구현하는 구현체 중 하나로 RequestMatcher 평가식을 기반으로 해당 평가식에 매치되는 AuthorizationManager 에게 권한 부여 처리를 위임하는 역할을 한다.
  3. RequestMatcherDelegationgAuthorizationManager 내부에서 매치되는 AuthorizationManager 구현 클래스가 있다면 해당 구현 클래스가 사용자의 권한을 체크한다.

  4. 적절한 권한이면 요청 프로세스를 이어간다.

  5. 적절한 권한이 아니라면 AccessDeniedException이 throw되고 ExceptionTranslationFilter가 예외를 처리하게 된다.

Spring Security 권한 부여 컴포넌트

AuthorizationFilter

public class AuthorizationFilter extends OncePerRequestFilter {

	private final AuthorizationManager<HttpServletRequest> authorizationManager;
	
  // AuthorizationFilter 객체가 생성될 때, AuthorizationManager를 DI 받음
  //  AuthorizationManager를 통해 권한 부여 처리를 진행
	public AuthorizationFilter(AuthorizationManager<HttpServletRequest> authorizationManager) {
		Assert.notNull(authorizationManager, "authorizationManager cannot be null");
		this.authorizationManager = authorizationManager;
	}

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

// AuthorizationManager의 check() 메서드를 호출해 적절한 권한 부여 여부를 체크
		AuthorizationDecision decision = this.authorizationManager.check(this::getAuthentication, request);
		this.eventPublisher.publishAuthorizationEvent(this::getAuthentication, request, decision);
		if (decision != null && !decision.isGranted()) {
			throw new AccessDeniedException("Access Denied");
		}
		filterChain.doFilter(request, response);
	}


}

URL을 통해 사용자의 액세스를 제한하는 권한 부여 Filter이다.

AuthorizationManager

@FunctionalInterface
public interface AuthorizationManager<T> {

	@Nullable
	AuthorizationDecision check(Supplier<Authentication> authentication, T object);

}

권한 부여 처리를 총괄하는 역할을 하는 인터페이스이다.

RequestMatcherDelegatingAuthorizationManager

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));
		}

    // RequestMatcherEntry 정보를 얻음
		for (RequestMatcherEntry<AuthorizationManager<RequestAuthorizationContext>> mapping : this.mappings) {
			// RequestMatcher 객체를 얻음. 메서드 체인 정보를 기반으로 생성됨
			RequestMatcher matcher = mapping.getRequestMatcher(); 
			MatchResult matchResult = matcher.matcher(request);
			if (matchResult.isMatch()) {   // AuthorizationManager 객체를 얻은 뒤, 사용자의 권한을 체크
				AuthorizationManager<RequestAuthorizationContext> manager = mapping.getEntry();
				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;
	}
}

AuthorizationManager의 구현 클래스 중 하나로, 직접 권한 부여 처리를 수행 하지 않고 RequestMatcher를 통해 매치되는 AuthorizationManager 구현 클래스에게 권한 부여 처리를 위임한다.

profile
BE 개발자를 꿈꾸는 대학생

0개의 댓글