250x250
jhs0129
프로그래밍
jhs0129
전체 방문자
오늘
어제
  • 분류 전체보기
    • 자격증
      • SQLD
      • 정보처리기사
    • 프로젝트
      • html csss js - todolist
      • JSP 방명록
      • 졸업작품
    • 공부기록
      • Java
      • Spring
      • Spring Security
      • Algorithm
      • JPA
      • DB
      • Servlet JSP
      • html
      • 기술공유
    • 잡다한 생각

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • AWS
  • NHN Cloud
  • codedeploy
  • 스프링시큐리티
  • spring framework
  • Spring Security
  • 프로젝트
  • spring boot
  • cicd
  • Spring Security Login
  • spring data jpa
  • nhn cloud 강의
  • rest docs
  • 스프링 프레임워크
  • 스프링
  • oAuth2
  • EC2
  • spring
  • github
  • JPA

최근 댓글

최근 글

티스토리

반응형
hELLO · Designed By 정상우.
jhs0129

프로그래밍

[추가] AuthorizeRequests vs AuthorizeHttpRequests
공부기록/Spring Security

[추가] AuthorizeRequests vs AuthorizeHttpRequests

2022. 12. 28. 14:50
320x100
반응형

목차

  • [이론] 스프링 시큐리티 1
  • [이론] 스프링 시큐리티2
  • [실습] 스프링 시큐리티 Form Login
  • [추가] CustomAuthenticationProvider vs DaoAuthenticationProvider
  • [이론] 스프링 시큐리티3
  • [이론] 스프링 시큐리티4
  • [추가] AuthorizeReqeusts vs AuthorizeHttpRequests
  • [실습] 스프링 시큐리티 Json data Login 처리
  • [실습] 스프링 시큐리티 JWT 설정
  • [실습] 스프링 시큐리티 JWT 처리
  • OAuth2

서론

이번글에선 Spring Security를 공부하면서 버전업에 의한 변경점에 대해서 다뤄볼 예정이다

기존에는 authorizeRequests를 사용하여 EndPoint에 관한 설정을 했지만 5.6버전 이후(아마도? docs보면 5.6부터 추가된 듯 보이긴 하는데) authorizeHttpRequests를 사용하는 것을 권장하고 있다

단순히 사용만 하는 것에 있어서는 그렇게 큰 차이는 없는 것 같지만 내부에서 동작이 크게 바뀌었기 때문에 한번 정리를 해보기로 한다

AuthorizeRequests

기존에 5.6버전 이전에 사용되는 방식이다

위 사진과 같이 SecurityFilterChain에 FilterSecurityInterceptor라는 필터가 추가된다

1번부터 순차적으로 동작을 보게되면

  1. SecurityContextHolder로 부터 Authentication객체 받아오기
  2. HttpServletRequest, HttpServletResponse, FilterChain을 이용하여 FilterInvocation 생성
  3. SecurityMetadataSource에 FilterInvocation를 전달하여 ConfigAtributes 가져오기
  4. AccessDecisionManager에 Authentication, FilterInvocation, ConfigAttribute 전달
  5. 접근 불가일 경우 예외 던짐
    • ExceptionTranslationFilter에서 예외 처리
  6. 접근 가능한 경우 filterChain타고 다음 filter로 전달

너무나도 많은 과정을 거치게 되고 권한이 필요없는 경로에서도 authentication에 관한 정보를 조회를 해야하는 단점이 있다

이러한 많은 과정을 단순화해서 만들어 진것이 authorizeHttpRequests이다

public class AffirmativeBased extends AbstractAccessDecisionManager {
    @Override
    public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes)
            throws AccessDeniedException {
        int deny = 0;
        //모든 경로에 대해서 권한을 확인한다
        for (AccessDecisionVoter voter : getDecisionVoters()) {
            int result = voter.vote(authentication, object, configAttributes);
            switch (result) {
            case AccessDecisionVoter.ACCESS_GRANTED:
                return;
            case AccessDecisionVoter.ACCESS_DENIED:
                deny++;
                break;
            default:
                break;
            }
        }
        if (deny > 0) {
            throw new AccessDeniedException(
                    this.messages.getMessage("AbstractAccessDecisionManager.accessDenied", "Access is denied"));
        }
        checkAllowIfAllAbstainDecisions();
    }
}

AuthorizeHttpRequests

5.6버전 이후 사용시 권장

기존과는 다르게 FilterSecurityInterceptor가 아닌 AuthorizationFilter라느 필터가 추가된다

사진만 봐도 과정이 매우 단순해 진 것을 볼 수 있다

1번부터 순차적으로 동작을 보게되면

  1. SecurityContextHolder로 부터 Authentication객체 받아오기
    • 이 부분에 대해서는 지연조회를 위해 Supplier에 한번 래핑되어 가져오게 된다
  2. Authorizationmanager에 Supplier-Authentication, HttpServletRequest 전달
  3. 접근 불가일 경우 예외 던짐
    • ExceptionTranslationFilter에서 예외 처리
  4. 접근 가능한 경우 filterChain타고 다음 filter로 전달

Spring Security Docs를 보게되면 Supplier에 한번 래핑을 함으로써 모든 요청에 대해서 권한이 필요한지를 보는 것이 아닌 권한이 요구되는 곳에서만 확인을 하게 된다고 한다

public final class RequestMatcherDelegatingAuthorizationManager implements AuthorizationManager<HttpServletRequest> {
    private final List<RequestMatcherEntry<AuthorizationManager<RequestAuthorizationContext>>> mappings;

    @Override
    public AuthorizationDecision check(Supplier<Authentication> authentication, HttpServletRequest request) {
        for (RequestMatcherEntry<AuthorizationManager<RequestAuthorizationContext>> mapping : this.mappings) {
            RequestMatcher matcher = mapping.getRequestMatcher();
            MatchResult matchResult = matcher.matcher(request);
            //요청받은 경로가 권한여부를 확인해야하는지 체크
            if (matchResult.isMatch()) {
                AuthorizationManager<RequestAuthorizationContext> manager = mapping.getEntry();
                return manager.check(authentication,
                        new RequestAuthorizationContext(request, matchResult.getVariables()));
            }
        }
        this.logger.trace("Abstaining since did not find matching RequestMatcher");
        return null;
    }
}

이러한 것을 모르더라도 추후 나온것이 더 좋다고 Spring을 믿고 사용해도 되지않을까라는 생각이다

지금당장 필요한 것은 아니지만 이런 것까지 굳이라는 생각보다는 동작을 파악하고 보면서 재밌는 시간이었던 것 같다

참고 사이트

Spring Security Docs

320x100
반응형

'공부기록 > Spring Security' 카테고리의 다른 글

[실습] 스프링 시큐리티 JWT 설정  (0) 2023.01.26
[실습] 스프링시큐리티 Json data Login 처리  (0) 2022.12.28
[이론] 스프링 시큐리티4  (0) 2022.12.28
[이론] 스프링 시큐리티3  (0) 2022.12.26
[추가]CustomAuthenticationProvider vs DaoAuthenticationProvider  (0) 2022.12.22
    '공부기록/Spring Security' 카테고리의 다른 글
    • [실습] 스프링 시큐리티 JWT 설정
    • [실습] 스프링시큐리티 Json data Login 처리
    • [이론] 스프링 시큐리티4
    • [이론] 스프링 시큐리티3
    jhs0129
    jhs0129
    공부기록 남기기

    티스토리툴바