Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Step2] 리펙터링 #6

Open
wants to merge 9 commits into
base: hyunssooo
Choose a base branch
from
Open

Conversation

hyunssooo
Copy link

안녕하세요, 부용님 step2가 많이 늦었습니다. 🥲🥲

SecurityFilterChain을 하나만 사용하게 하려고 하니깐 SecurityFilterChain#matches 을 true로만 리턴하게 되더라고요.
이 부분이 맞는 방향인지 모르겠네요 ㅠ
그래서 모든 요청이 등록한 필터를 모두 타고 있습니다..!

Copy link
Collaborator

@byjo byjo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

현수님 2단계 오래 고민하셨다고 하셨는데 구조는 잘 잡힌 것 같아요!
사소한 부분 몇 가지만 정리해보시죠~

}

@Override
public boolean matches(HttpServletRequest request) {
return requestMatcher.matches(request);
return true;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SecurityFilterChain을 하나만 사용하게 하려고 하니깐 SecurityFilterChain#matches 을 true로만 리턴하게 되더라고요.
이 부분이 맞는 방향인지 모르겠네요 ㅠ
그래서 모든 요청이 등록한 필터를 모두 타고 있습니다..!

요구사항으로 의도했던 바는 모든 요청이 등록한 모든 필터를 타는 것이 맞구요.
이 경우 requestMatcher를 AnyRequestMatcher로 사용하시면 됩니다!

public class AnyRequestMatcher implements RequestMatcher {
    public static final RequestMatcher INSTANCE = new AnyRequestMatcher();

    private AnyRequestMatcher() {
    }

    @Override
    public boolean matches(HttpServletRequest request) {
        return true;
    }
}

SecurityFilterChain에 있는 인증 Filter의 경우 인증 요청의 계약(path, http method, header...)이 명확하기 때문에, 원하는 요청만 처리할 수 있고, 인가 Filter에서는 AuthorizeRequestMatcherRegistry 를 사용해 요청에 따른 인가를 적용할 수 있죠.
인증, 인가 외에 보안이나 예외 처리, 설정을 위한 Filter들은 모든 요청에 적용되어야 하구요.

위의 이유로 SecurityFilterChain 을 하나만 사용하는 요구사항을 추가해봤습니다!

구성하는 Filter 목록이 완전히 달라져야하는 경우에는 여러개의 SecurityFilterChain을 사용하는데요.
저는 사용을 안해봤어서... 현수님이 요런 사례를 발견하시면 공유 부탁드려요 ㅋㅋㅋ

@@ -89,4 +73,8 @@ public AuthenticationManager authenticationManager() {
return new AuthenticationManager(new UsernamePasswordAuthenticationProvider(userDetailsService));
}

@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(new LoginUserArgumentResolver());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오오 ArgumentResolver 사용 좋네요! 👏👏

Comment on lines 26 to 28
final HttpServletRequest request = (HttpServletRequest) webRequest.getNativeRequest();
final SecurityContext context = (SecurityContext) request.getSession().getAttribute("SPRING_SECURITY_CONTEXT");
final String email = context.getAuthentication().getPrincipal().toString();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SecurityContextHolder를 사용해서 가져올 수도 있겠네요!

SecurityContextHolder.getContext().getAuthentication();

(+) 조금 더 나아가보면, 지금은 Authentication의 Pricipal로 String(username)을 사용하고 있는데요.
Pricipal로 객체를 리턴할 수도 있어요!

Comment on lines 37 to 41
SecurityContext context = Optional.ofNullable(
(SecurityContext) httpServletRequest.getSession()
.getAttribute(SecurityContextHolder.SPRING_SECURITY_CONTEXT_KEY)
)
.orElseGet(() -> securityContextRepository.loadContext(httpServletRequest));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

주입된 securityContextRepository가 HttpSessionSecurityContextRepository 인데 동일한 일을 하고 있지 않나요?


import nextstep.security.authentication.Authentication;

public interface RoleManager {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 인터페이스의 구현체 중에는 Role을 확인하지 않는 것들도 있어서 조금 어색한 느낌이 드는데 어떠신가요?

Comment on lines 36 to 38
public static final String PERMIT_ALL = "permitAll";
public static final String DENY_ALL = "denyAll";
public static final String AUTHENTICATED = "authenticated";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 값들은 더이상 사용하지 않겠네요.

}

public AuthorizeRequestMatcherRegistry hasAuthority(String... authorities) {
return access(new AuthorizationRoleManager(authorities));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Manger를 매핑하는 방식으로 변경하셨군요! 👍👍👍

추가로 보자면 어노테이션을 사용한 인가 설정의 경우 이전 구조처럼 인가에 필요한 정보를 attribute로 관리하는 방식으로 동작하는데요.

이 내용은 스프링 시큐리티의 PreAuthorizeAuthorizationManagerPostAuthorizeAuthorizationManager 의 코드를 참고해 학습해볼 수 있습니다!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants