1. 문제점
스프링 부트와 AWS로 혼자 구현하는 웹서비스 책을 기반으로 새로운 프로젝트를 진행하던중
스프링 부트의 버전차이로 인해 구글 로그인 및 OAuth2 하는데 문제가 발생했다.
우선 SecurityConfig 파일도 WebSecurityConfigurerAdapter 을 상속해서 작성했는데 스프링 Security 6 기준으로 사용을 할수 없다고 한다.( deprecated )
그래서 하루종일 구글 서칭도 하고 Chat GPT 한테 물어보면서 상속을 지우고 SecurityFilterChain 을 리턴하는 식으로 변경하였으나 로그인을 해서 session에 등록이 됐는데도 로그인으로 redirect 되고 그랬다.
1.1. 개발환경
- Spring Boot 3.2.1
- Java 17
2. 1차 수정본
<java />
package com.omcst.demo.config.auth;
import com.omcst.demo.domain.user.Role;
import lombok.RequiredArgsConstructor;
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.WebSecurityCustomizer;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
@RequiredArgsConstructor
/**
* EnableWebSecurity : Spring Security 설정들을 활성화 시켜준다.
*/
@EnableWebSecurity // 1
@Configuration
public class SecurityConfig{
private final CustomOAuth2UserService customOAuth2UserService;
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http, HandlerMappingIntrospector introspector) throws Exception{
http.csrf(AbstractHttpConfigurer::disable)
.sessionManagement((sessionManagement) ->
sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.formLogin(AbstractHttpConfigurer::disable)
.httpBasic(AbstractHttpConfigurer::disable)
.authorizeHttpRequests((authorizeRequest) -> authorizeRequest.
requestMatchers(new AntPathRequestMatcher("/","GET"),
new AntPathRequestMatcher("/board","GET"),
new AntPathRequestMatcher("/image/**","GET"),
new AntPathRequestMatcher("/css/**","GET"),
new AntPathRequestMatcher("/js/**","GET"))
.permitAll() // "/"와 "/css/**", "/image/**", "/js/**"에 대해 모든 권한 허용
// .requestMatchers(new MvcRequestMatcher(introspector,"/board/**")).hasRole(Role.USER.name())
.anyRequest().permitAll()
)
.logout(logout -> logout
.logoutSuccessUrl("/board"))
.oauth2Login(oauth2Login ->
oauth2Login.userInfoEndpoint(userInfoEndpointConfig ->
userInfoEndpointConfig.userService(customOAuth2UserService))
.defaultSuccessUrl("/board")
)
;
return http.build();
}
}
여러 블로그와 GPT 를 통해 만들어낸 소스이다. gpt도 최신 데이터가 기준이 아니다 보니 원하는 대답을 듣기까지 굉장히 오래걸렸다. 그와중에 authorizeRequests().antMatchers가 안나오길래 쓰지말라고 계속 얘기해도 그냥 무시하고 똑같은 소스만 계속 보여줘서 포기할까도 싶었다.
지금 소스에서 잘 돌아갔으면 좋았겟지만 Role 있는 경로에 가려고 하면 계속 로그인을 요구하고 설정한 SuccessUrl로 이동했다. 한참을 찾다가 겨우겨우 찾은 한 블로그에서 나와 비슷한 증상을 겪는글을 보고 바로 수정했더니 한방에 해결됐다.
3. 2차 수정본(최종)
<java />
package com.omcst.demo.config.auth;
import com.omcst.demo.domain.user.Role;
import lombok.RequiredArgsConstructor;
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.WebSecurityCustomizer;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
@RequiredArgsConstructor
/**
* EnableWebSecurity : Spring Security 설정들을 활성화 시켜준다.
*/
@EnableWebSecurity // 1
@Configuration
public class SecurityConfig{
private final CustomOAuth2UserService customOAuth2UserService;
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http, HandlerMappingIntrospector introspector) throws Exception{
http.csrf(AbstractHttpConfigurer::disable)
.headers((header) -> header.frameOptions(HeadersConfigurer.FrameOptionsConfig::disable))
// .sessionManagement((sessionManagement) ->
// sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.formLogin(AbstractHttpConfigurer::disable)
.httpBasic(AbstractHttpConfigurer::disable)
.authorizeHttpRequests((authorizeRequest) -> authorizeRequest.
requestMatchers(new AntPathRequestMatcher("/"),
new AntPathRequestMatcher("/css/**"),
new AntPathRequestMatcher("/image/**"),
new AntPathRequestMatcher("/js/**"),
new AntPathRequestMatcher("/profile"),
new AntPathRequestMatcher("/board"))
.permitAll() // "/"와 "/css/**", "/image/**", "/js/**"에 대해 모든 권한 허용
.requestMatchers(new AntPathRequestMatcher("/board/**")).hasRole(Role.USER.name())
// .requestMatchers(new MvcRequestMatcher(introspector,"/board/**")).hasRole(Role.USER.name())
.anyRequest().authenticated()
)
.logout(logout -> logout
.logoutSuccessUrl("/board")) // logout 시
.oauth2Login(oauth2Login ->
oauth2Login.userInfoEndpoint(userInfoEndpointConfig ->
userInfoEndpointConfig.userService(customOAuth2UserService))
.defaultSuccessUrl("/board",true)
) // AntPathRequestMatcher.antMatcher()
;
return http.build();
}
}
어느부분이 문제였는지 확인은 안해봣지만 우선 바뀐부분은 AntPathRequestMatcher 뒤에 "GET" 부분과
sessionManagement 를 주석처리하고 headers 부분을 추가해 주었더니 내가 원하는 결과가 나왔다.
혹시 필요할수도 있으니 pom.xml 에 관련된 부분도 추가해보겠다.
<java />
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
</dependency>
참고한 블로그는 개발잠 블로그 인데 문제 해결능력도 그렇고 공식문서를 보는걸 배워야한다고 느꼇다.
'IT 기술 > 스프링[Spring]' 카테고리의 다른 글
스프링 공부 (0) | 2021.01.29 |
---|---|
SqlMapClientFactoryBean , SqlSessionFactoryBean (0) | 2021.01.05 |
JdbcTemplate , SqlMapClientDaoSupport (0) | 2021.01.04 |
Unable to find setter method for attribute :[commandName] 에러 (0) | 2020.12.22 |
@GetMapping , @PostMapping 등 어노테이션 import 에러 (0) | 2020.12.21 |