<현상>
아래는 브라우저 모습
아래 캡쳐에서 개발자도구에서 login으로 계속 리다이렉션을 보내는 것을 확인.
status code 302는 redirection임.
<원인>
아래는 토이프로젝트의 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() : 인증된 사람만 통과