작성
·
810
·
수정됨
0
에러 메시지는 아래와 같습니다.
***************************
APPLICATION FAILED TO START
***************************
Description:
The dependencies of some of the beans in the application context form a cycle:
┌─────┐
| oauth2UserService defined in file [D:\GooGoo\out\production\classes\eunhye\GooGoo\config\oauth\Oauth2UserService.class]
↑ ↓
| securityConfig defined in file [D:\GooGoo\out\production\classes\eunhye\GooGoo\config\security\SecurityConfig.class]
└─────┘
Action:
Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true.
Process finished with exit code 1
oauth2UserService와 securityConfig가 cycle을 이루고 있다.
뭔가 구조가 잘못됐다는 것을 알 수 있었습니다만...
전 강의 잘 듣고 잘 코드 쳤다고 생각이 되거든요ㅠ
스스로를 의심하며 아무리 코드를 쳐다봐도 잘못된 점을 모르겠어서 질문 올립니다.
다음은 관련된 코드들입니다.
Oauth2UserService.java
package eunhye.GooGoo.config.oauth;
import eunhye.GooGoo.config.security.SecurityDetails;
import eunhye.GooGoo.dto.UserDTO;
import eunhye.GooGoo.entity.UserEntity;
import eunhye.GooGoo.entity.UserRole;
import eunhye.GooGoo.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class Oauth2UserService extends DefaultOAuth2UserService {
private final UserRepository userRepository;
private final PasswordEncoder passwordEncoder;
// 구글로부터 받은 userRequest 데이터에 대해 후처리하는 함수
@Override
public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException{
OAuth2User oauth2User = super.loadUser(userRequest);
// 회원가입 강제 진행
String provider = userRequest.getClientRegistration().getClientId();
String providerId = oauth2User.getAttribute("sub");
String userNickname = provider+"_"+providerId;
String userEmail = oauth2User.getAttribute("email");
String userPassword = passwordEncoder.encode("겟인데어");
UserRole authority = UserRole.USER;
UserEntity userEntity = userRepository.findByUserEmail(userEmail);
if(userEntity == null){
userEntity = UserEntity.builder()
.userNickname(userNickname)
.userEmail(userEmail)
.userPassword(userPassword)
.authority(authority)
.provider(provider)
.providerId(providerId)
.build();
userRepository.save(userEntity);
}
return new SecurityDetails(userEntity, oauth2User.getAttributes());
}
}
SecurityConfig.java
package eunhye.GooGoo.config.security;
import eunhye.GooGoo.config.oauth.Oauth2UserService;
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.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig{
private final AuthenticationFailureHandler customFailureHandler;
private final Oauth2UserService oauth2UserService;
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/user/**").authenticated()
.antMatchers("/admin/**").access("hasRole('ADMIN')")
.anyRequest().permitAll()
.and()
.formLogin()
.loginPage("/login")
.loginProcessingUrl("/login")
.defaultSuccessUrl("/home")
.usernameParameter("userEmail").passwordParameter("userPassword")
.failureHandler(customFailureHandler)
.and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/login")
.and().oauth2Login()
.loginPage("/login").defaultSuccessUrl("/home")
.userInfoEndpoint().userService(oauth2UserService);
return http.build();
}
}
SecurityDetails.java
package eunhye.GooGoo.config.security;
import eunhye.GooGoo.entity.UserEntity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.oauth2.core.user.OAuth2User;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
@Data
public class SecurityDetails implements UserDetails, OAuth2User {
// 일반 로그인
private final UserEntity userEntity;
// OAuth 로그인 (Google)
private Map<String, Object> attributes;
public SecurityDetails(UserEntity userEntity){
this.userEntity = userEntity;
}
public SecurityDetails(UserEntity userEntity, Map<String, Object> attributes){
this.userEntity = userEntity;
this.attributes = attributes;
}
@Override
public Map<String, Object> getAttributes() {
return attributes;
}
@Override
public String getName() {
return userEntity.getId()+"";
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
Collection<GrantedAuthority> authorities = new ArrayList<>();
authorities.add(new GrantedAuthority() {
@Override
public String getAuthority() {
return userEntity.getAuthority().toString();
}
});
return authorities;
}
@Override
public String getPassword() {
return userEntity.getUserPassword();
}
@Override
public String getUsername() {
return userEntity.getUserEmail();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
추가적인 코드가 필요하다면 아래 깃헙 링크 참고해주세요
감사합니다. 덕분에 해결했습니다. 왜 해결됏는지 이유는모르겠지만..감사합니다