0

I need your help with spring-security. I have a repository with the code of my application in which I want to try to make spring-sequrity for authorization and authentication. The fact is that when I run a project, the terminal gives this error:

The dependencies of some of the beans in the application context form a cycle: sequrityConfiguration (field private org.springframework.security.core.userdetails.UserDetailsService com.social_app_backend.config.SequrityConfiguration.userDetailsService) userServiceImpl defined in file [J:\backend_for_social_app\target\classes\com\social_app_backend\service\UserServiceImpl.class]

I used to run this code easily and it worked great. Tell me, what am I doing wrong, where is my mistake? Here is the repository, branch: connectingToDatabaseWithSequrity

SecurityConfiguration.java

package com.social_app_backend.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
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.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
@EnableWebSecurity
public class SequrityConfiguration extends WebSecurityConfigurerAdapter {

   @Autowired
   private UserDetailsService userDetailsService;

   @Override
   protected void configure(AuthenticationManagerBuilder auth) throws Exception {
       auth.authenticationProvider(daoauthenticationProvider());
   }

   @Bean
   public AuthenticationProvider daoauthenticationProvider() {
     DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
     daoAuthenticationProvider.setPasswordEncoder(passwordEncoder());
     daoAuthenticationProvider.setUserDetailsService(userDetailsService);
     return daoAuthenticationProvider;
   }

   @Bean
   public PasswordEncoder passwordEncoder() {
       return new BCryptPasswordEncoder();
   }

   @Override
   protected void configure(HttpSecurity http) throws Exception {
   http.csrf().disable().cors().disable()
           .authorizeRequests()
           .antMatchers(HttpMethod.POST, "/registrate")
           .anonymous()
           .anyRequest().authenticated().and().httpBasic();
  }
}

UserServiceImpl.java

package com.social_app_backend.service;

import com.social_app_backend.dao.UserDao;
import com.social_app_backend.dto.UserDto;
import com.social_app_backend.entity.User;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class UserServiceImpl implements UserDetailsService, UserService {

   private final UserDao userDao;
   private final PasswordEncoder passwordEncoder;

   @Override
   public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
    return userDao.findByUsername(username);
   }


   @Override
   public String createUser(UserDto userDto) {
    User user = new User();
    user.setUsername(userDto.getUsername());
    user.setPassword(passwordEncoder.encode(userDto.getPassword()));
    user.setRole("ROLE_USER");
    userDao.save(user);
    return user.getUsername();
   }
}
  • 1
    The following things can be removed: you dont need to set the `authenticationProvider` manually, you dont need to create the `DaoAuthenticationProvider` manually. These things will be done automatically – Toerktumlare May 02 '22 at 13:22

1 Answers1

0

From the code, it seems that the Circular dependency is getting formed as you have used PasswordEncoder in UserServiceImpl as well as in SecurityConfig So, for creating SecurityConfig, Spring needs UserServiceImpl bean and UserServiceImpl needs PasswordEncoder defined in SecurityConfig.
To remove the cycle, create a separate Configuration class with @Configuration, shift the PasswordEncoder bean creation in that config, and autowire it in SequrityConfiguration as well as UserServiceImpl

Update: You can do it Like below:

@Configuration
public class MyConfiguration{

   @Bean
   public PasswordEncoder passwordEncoder() {
       return new BCryptPasswordEncoder();
   }

}

In SecurityConfig class,

@Configuration
@EnableWebSecurity
public class SequrityConfiguration extends WebSecurityConfigurerAdapter {

   @Autowired
   private UserDetailsService userDetailsService;

   @Autowired
   private PasswordEncoder passwordEncoder;
....

   @Bean
   public AuthenticationProvider daoauthenticationProvider() {
     DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
     daoAuthenticationProvider.setPasswordEncoder(passwordEncoder);
     daoAuthenticationProvider.setUserDetailsService(userDetailsService);
     return daoAuthenticationProvider;
   }

}
Chetan Ahirrao
  • 1,454
  • 11
  • 16
  • I managed to do it,thank you. I have only one question, can you show or tell me how to set validation pattern to password??? Thank you) –  May 02 '22 at 19:26
  • 1
    If the answer is the solution, please accept or upvote it for the benefit of others. You can ask the validation pattern as a separate question. – Chetan Ahirrao May 03 '22 at 02:08