Spring Security - 권한 부여

uudean·2023년 7월 12일
0

Spring

목록 보기
10/13

권한 부여 처리 흐름

  • AuthorizationFilterspring Security Filter Chain 에서 URL을 통해 사용자 액세스를 제한하는 권한 부여 Filter이다.
  • AuthorizationFilterSecurityContextHolder 로 부터 Authentication 을 얻은 후 AuthenticationHttpServletRequestAuthorizationManager 에게 전달한다.

AuthorizationManger

  • 권한 부여를 총괄하는 인터페이스
  • RequestMatcherDelegatingAuthorizationManager 가 구현체 중 하나

RequestMatcherDelegatingAuthorizationManager

  • RequestMatcher 평가식을 기반으로 해당 평가식에 매치되는 AuthorizationManger 에게 권한 부여 처리를 위임하는 역할
  • RequestMatcherDelegatingAuthoriztionManager 내부에서 매치되는 AuthorizationManager 구현 클래스가 있다면 해당 구현 클래스가 사용자의 권한을 체크한다.
  • 적절한 권한이라면 계속해서 프로세스를 진행하고 , 적절한 권한이 아니라면 AccessDeniedException 이 throw 되고 ExceptionTranslationFilterAccessDeniedException 을 처리하게 된다.

권한 부여 컴포넌트

AuthorizationFilter

public class AuthorizationFilter extends OncePerRequestFilter {

	private final AuthorizationManager<HttpServletRequest> authorizationManager;
  	
    ...
  	...
    
    public AuthorizationFilter
    	(AuthorizationManager<HttpServletRequest> authorizationManager) {
    	Assert.notNull(authorizationManager, "...");
        this.authorizationManager = authorizationManager;
        }
    
    @Override    
    protected void doFilerInternal
    	(HttpServletRequest request,
       	 HttpServletResponse response,
         FilterChain chain) throws ServletException, IOException {
         AuthorizationDecision decision = this.authorizationManager
         									  .check(this::getAuthentication, request);
         ...
         ...
         
         filterChain.doFilter(request,response);
     }
    	...
    }
  • AuthorizationFilter 객체가 생성될 때, AuthorizationManager 를 DI 받는다.
  • DI 받은 AuthorizationManagercheck() 메서드 호출을 통해 적절한 권한 부여 여부를 체크한다.
    • AuthorizationManager 의 구현 클래스에 따라 check() 메서드는 권한 체크 로직이 다르다.

AuthorizationManager

@FunctionalInterface
public interface AuthorizationManager<T> {
	...
    ...
    
    @Nullable
    AuthorizationDecision check(Supplier<Authentication> authentication , T object);
}    
  • AuthorizationManger 인터페이스는 check() 메서드 하나만 정의되어 있고 Supplier 와 제너릭 타입의 객체를 파라미터로 갖는다.

RequestMatcherDelegatingAuthorizationManager

public final RequestMatcherDelegatingAuthorizationManager
  implements AuthorizationManager<HttpServletRequest> {
  	...
    ...
    
    @Override
    public AuthorizationDecision check(Supplier<Authentication> authentication,
    								   HttpServletRequest request) {
 		if(this.logger.isTraceEnabled()) {
           this.logger.trace(LogMessage.foramt("...",request);
        } 
        
   		for(RequestMathcherEntry<AuthorizationManager<ResultAuthorizationContext>>
        		mapping : this.mappings) {
           RequestMatcher matcher = mapping.getRequestMatcher();
           if (matchResult.isMatch()) {   
				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("...");
		  return null;
    }
}     
  • check() 메서드 내부에서 for 루프를 돌며 RequestMatcherEntry 정보를 얻은 후 ResultMatcher 객체를 얻는다.
  • matchResult.isMatch() 가 true 이면 AuthorizationManager 객체를 얻는 후, 사용자 권한을 체크한다.
    • ResultMatcherSecurityConfiguration 에서 .antMatchers("/orders/**").hasRole("ADMIN") 와 같은 메서드 체인 정보를 기반으로 생성된다.

0개의 댓글

관련 채용 정보