본문 바로가기

코딩/예외 창고

spring scurity 예외: 페이지가 작동하지 않습니다. localhost에서 리디렉션한 횟수가 너무 많습니다.

<현상>

아래는 브라우저 모습

오류

아래 캡쳐에서 개발자도구에서 login으로 계속 리다이렉션을 보내는 것을 확인.

status code 302는 redirection임.

/login으로 계속 리다이렉션함.

 

<원인>

아래는 토이프로젝트의 config java파일 코드임. 아래의 configure()함수에서 빌더패턴을 사용해 설정하는데 설정 순서가 중요했다.!!

 

package pnu.problemsolver.myorder.config;

import io.jsonwebtoken.Jwt;
import lombok.RequiredArgsConstructor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.filter.OncePerRequestFilter;
import pnu.problemsolver.myorder.filter.JwtAuthenticationFilter;
import pnu.problemsolver.myorder.security.JwtTokenProvider;

import javax.servlet.Filter;
import javax.servlet.http.HttpSession;

@Configuration
@EnableWebSecurity //기본적인 웹보안을 활성화
@RequiredArgsConstructor
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    private final ApplicationContext applicationContext;
   

    @Override
    protected void configure(HttpSecurity http) throws Exception {
//        http.
//                authorizeRequests()
//                .antMatchers("/api/hello").permitAll()
//                .anyRequest().authenticated();

        //빌더패턴을 사용함.
        http
                .httpBasic().disable()//기본 로그인 페이지 사용x
                .csrf().disable()   //REST API 사용하기 때문에 csrf x
                .authorizeRequests()
                .antMatchers("**").hasRole("USER")  //여기가 문제임. 아래에서는 permitAll()로 접근가능하다고 했는데 여기서는 접근 불가능하게 설정함. 먼저 나온 것이 먼저 적용되는 듯.
                .antMatchers("/store/list", "/", "/login").permitAll()
//                .antMatchers("/admin/**").hasRole("ADMIN")     //ADMIN만 접근 가능
                .anyRequest().authenticated()   //나머지 요청들은 권한이 있어야만 접근 가능
                .and()
                .formLogin()
                .loginPage("/login")    //로그인 페이지
                .defaultSuccessUrl("/store/list") //로그인 성공 후
                .and()
                .logout()
                .logoutSuccessUrl("/store/list")//로그아웃 성공
                .and()
                .exceptionHandling()
                .and()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); //jwt사용을 위해 session해제.
    }


}

antMatcher 설정시 먼저 등록한게 먼저 적용되는 듯.

즉 모든 url에 대해 USER권한이 필요하다고 했으니 자동으로 loginPage("/login")에서 설정한 대로 /login으로 이동. 하지만 /login도 permitAll()이 아니라서 자꾸 리다이렉션 하는 것임. 밑에 "/login"이 permitAll되어 있지만 그전에 모든 URL에 대해서 hasRole(USER)가 있어서 접근하지 못한다.

 

겹치지 않게 쓰는게 젤 좋고 겹칠 때는 작은 부분만 설정하고 나머지는 anyRequest().permitAll() 또는 anyRequest.authenticated()로 설정하자.

 

permitAll() : 모두 허용

authenticated() : 인증된 사람만 통과