cso6005 / Auth_Project

회원 인증, 인가 관련 프로젝트
0 stars 0 forks source link

로그인/회원가입 요청의 경우, SecurityConfig에서 PermitAll() 설정, doFilter에서 헤더 조건문 추가 해주기 #3

Open cso6005 opened 1 year ago

cso6005 commented 1 year ago

SecurityConfig 설정


    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {

        http.cors().and().csrf().disable()
        .exceptionHandling()
        .accessDeniedHandler(customAccessDeniedHandler)
        .authenticationEntryPoint(customAuthenticationEntryPoint)
        .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

        // 인가 권한 허용
        http
        .authorizeRequests()
        .antMatchers("/board/test").hasRole("USER")
            .antMatchers("/auth/**").permitAll() // 로그인, 회원가입 요청 시, 인가 권한 허용
            .anyRequest().authenticated()
        ;   

        http.addFilterBefore(new JwtAuthenticationFilter(jwtProvider, accountDetailsService),
                UsernamePasswordAuthenticationFilter.class)
;

        return http.build();
    }
cso6005 commented 1 year ago
cso6005 commented 1 year ago

Web Ignore 과 PermitAll 의 차이

이 두 개을 혼동하면 안된다. 공부 덜 했을 때, 둘 차이를 잘 몰랐음..

Web Ignore

시큐리티는 기본적으로 모든 자원 요청에 대해 인증, 인가를 거친다. 그러나, 정적인 자원들에 대해서는 반복적인 인증, 인가가 악영향을 줄 수 있다.

예를 들어, 특정 url 에 접근했을 때, 뷰가 렌더링 된다고 할 때, 이미 url 에 접근할 수 있다는 인가를 받으면 그 화면이 바로 랜더링 된다. 그렇지만 스프링 스큐리는 기본적으로 모든 접근에 대해 인증, 인가를 검색하기 때문에 이 url 을 랜더링 하는데 필요한 정적인 파일 css, html, js 파일들을 모두 다시 또 검사한다. 이는 쓸데 없는 반복이기에 정적인 파일에 한해서는 검사를 스킵한다.

=> 정적인 자원에 한한 요청에 대해서는 WebIgnore 해주기

PermitAll()

둘 모두 인증을 거치지 않은 사용자를 접근가능하도록 한다는 점이 같다. 하지만 동작 과정에 대해서 전혀 다르다.

PermitAll() 의 경우, 인증이 필요없다고 하지만, 반드시 FilterSecurityInterceptor까지 온 다음 DispatcherServlet 으로 넘어간다. 즉, 인증이 필요 없어도 시큐리티 필터를 거친다는 것이다. 그에 반면 WebIgnore 는 시큐리티 필터 자체를 아예 거치지 않는다.!!

로그인, 회원가입 url(헤더 토큰없음) 과 로그인, 회원가입이 아닌 url(헤더 토큰없음) 둘 경우가 다른 처리가 이뤄져야 한다.

비로그인 상태로 접속을 시도했을 때, 즉, 토큰이 헤더에 없는 경우에도 doFilterInternal (토큰 확인) 필터를 거친다.

그래서. if (StringUtils.hasText(authorization)) { 처리를 해줌으로써 헤더에 토큰이 있는 경우에만, 토큰 인증을 시도하게 조건문 처리를 해준다. 해당 처리를 통해 토큰 인증 내 예외가 발생하지 않고 해당 단계를 통과하도록 한다.

그리고, 로그인, 회원가입이 아닌 즉, PermitAll 하지 않은 자원 요청에 경우, AuthenticationException 를 내게 된다. 처음에는 AccessDeniedException이 발생하나, isAnonymous()에 해당하기 때문에 AuthentiationException으로 전환되고, AuthenticationEntryPoint로 검사가 넘어가게 되는 것이다.

로그인, 회원가입의 경우, 인증되지 않은 상태, 권한이 되지 않는 상태여도 로그인 처리 로직이 처리 됨으로써, 권한을 얻게 되므로 정상 처리된다.

=> 로그인, 회원가입의 경우, 인증(토큰을 받급받은 자 즉, 인증된 사용자인지)을 거치지 않는다. 하지만 그래도 UsernamePasswordAuthenticationFilter 등등 시큐리티 필터를 거쳐야 한다. => 그러므로, 로그인, 회원가입 등 자원의 경우, PermitAll 설정을 해준다.

        http
                .authorizeRequests()
                .antMatchers("/").permitAll()
                .anyRequest().authenticated();