Conversation
byjo
left a comment
There was a problem hiding this comment.
현수님 2단계 오래 고민하셨다고 하셨는데 구조는 잘 잡힌 것 같아요!
사소한 부분 몇 가지만 정리해보시죠~
| @Override | ||
| public boolean matches(HttpServletRequest request) { | ||
| return requestMatcher.matches(request); | ||
| return true; |
There was a problem hiding this comment.
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을 사용하는데요.
저는 사용을 안해봤어서... 현수님이 요런 사례를 발견하시면 공유 부탁드려요 ㅋㅋㅋ
|
|
||
| @Override | ||
| public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) { | ||
| resolvers.add(new LoginUserArgumentResolver()); |
There was a problem hiding this comment.
오오 ArgumentResolver 사용 좋네요! 👏👏
| final HttpServletRequest request = (HttpServletRequest) webRequest.getNativeRequest(); | ||
| final SecurityContext context = (SecurityContext) request.getSession().getAttribute("SPRING_SECURITY_CONTEXT"); | ||
| final String email = context.getAuthentication().getPrincipal().toString(); |
There was a problem hiding this comment.
SecurityContextHolder를 사용해서 가져올 수도 있겠네요!
SecurityContextHolder.getContext().getAuthentication();
(+) 조금 더 나아가보면, 지금은 Authentication의 Pricipal로 String(username)을 사용하고 있는데요.
Pricipal로 객체를 리턴할 수도 있어요!
| SecurityContext context = Optional.ofNullable( | ||
| (SecurityContext) httpServletRequest.getSession() | ||
| .getAttribute(SecurityContextHolder.SPRING_SECURITY_CONTEXT_KEY) | ||
| ) | ||
| .orElseGet(() -> securityContextRepository.loadContext(httpServletRequest)); |
There was a problem hiding this comment.
주입된 securityContextRepository가 HttpSessionSecurityContextRepository 인데 동일한 일을 하고 있지 않나요?
|
|
||
| import nextstep.security.authentication.Authentication; | ||
|
|
||
| public interface RoleManager { |
There was a problem hiding this comment.
이 인터페이스의 구현체 중에는 Role을 확인하지 않는 것들도 있어서 조금 어색한 느낌이 드는데 어떠신가요?
| public static final String PERMIT_ALL = "permitAll"; | ||
| public static final String DENY_ALL = "denyAll"; | ||
| public static final String AUTHENTICATED = "authenticated"; |
| } | ||
|
|
||
| public AuthorizeRequestMatcherRegistry hasAuthority(String... authorities) { | ||
| return access(new AuthorizationRoleManager(authorities)); |
There was a problem hiding this comment.
Manger를 매핑하는 방식으로 변경하셨군요! 👍👍👍
추가로 보자면 어노테이션을 사용한 인가 설정의 경우 이전 구조처럼 인가에 필요한 정보를 attribute로 관리하는 방식으로 동작하는데요.
이 내용은 스프링 시큐리티의 PreAuthorizeAuthorizationManager나 PostAuthorizeAuthorizationManager 의 코드를 참고해 학습해볼 수 있습니다!
안녕하세요, 부용님 step2가 많이 늦었습니다. 🥲🥲
SecurityFilterChain을 하나만 사용하게 하려고 하니깐
SecurityFilterChain#matches을 true로만 리턴하게 되더라고요.이 부분이 맞는 방향인지 모르겠네요 ㅠ
그래서 모든 요청이 등록한 필터를 모두 타고 있습니다..!