簡體   English   中英

Bean Cycle Spring 安全

[英]Bean Cycle Spring Security

我正在開發一個 Spring 引導 web 應用程序。 問題出在登錄場景中,並且 ima 堆積在循環中。 寫道依賴關系是相互關聯的,我無法弄清楚究竟是如何以及為什么

描述:

application context中的一些bean的依賴關系形成了一個循環:

┌─────┐
|  webSecurityConfig (field boot.service.UserDetailsServiceImpl boot.configs.WebSecurityConfig.userDetailsService)
↑     ↓
|  userDetailsServiceImpl (field org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder boot.service.UserDetailsServiceImpl.bCryptPasswordEncoder)
└─────┘

我該如何解決這個問題,伙計們? 我的課程:

@Service
public class UserDetailsServiceImpl implements UserDetailsService {

    @PersistenceContext
    private EntityManager em;

    @Autowired
    UserRepository userRepository;

    @Autowired
    RoleRepository roleRepository;

    @Autowired
    BCryptPasswordEncoder bCryptPasswordEncoder;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userRepository.findByUsername(username);

        if (user == null) {
            throw new UsernameNotFoundException("User not found");
        }

        return user;
    }

    public User findUserById(Long userId) {
        Optional<User> userFromDb = userRepository.findById(userId);
        return userFromDb.orElse(new User());
    }

    public List<User> allUsers() {
        return userRepository.findAll();
    }

    public boolean saveUser(User user) {
        User userFromDB = userRepository.findByUsername(user.getUsername());

        if (userFromDB != null) {
            return false;
        }

        user.setRoles(Collections.singleton(new Role(1L, "ROLE_User")));
        user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
        userRepository.save(user);
        return true;
    }

    public boolean deleteUser(Long userId) {
        if (userRepository.findById(userId).isPresent()) {
            userRepository.deleteById(userId);
            return true;
        }
        return false;
    }

    public List<User> usergtList(Long idMin) {
        return em.createQuery("SELECT u from User u WHERE u.id > :paramId", User.class)
                .setParameter("paramId", idMin).getResultList();
    }


}

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    UserDetailsServiceImpl userDetailsService;

    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .csrf()
                    .disable()
                .authorizeRequests()
                    .antMatchers("/registration").not().fullyAuthenticated()
                    .antMatchers(("/admin/**")).hasRole("ADMIN")
                    .antMatchers("/", "/resources/**").permitAll()
                .anyRequest().authenticated()
                .and()
                    .formLogin()
                    .loginPage("/login")
                    .defaultSuccessUrl("/")
                    .permitAll()
                .and()
                    .logout()
                    .permitAll()
                    .logoutSuccessUrl("/");
    }

    @Autowired
    protected void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
    }
}

幫我弄清楚,我的腦袋已經壞了,谷歌也幫不上忙

如果您從 Spring 閱讀UserDetailsService ervice 接口的 javadoc - 實現的責任應該是“加載用戶數據”。

您實施的問題在於您打算將其用於更多目的,即“節省用戶”。 要保存用戶,您的UserDetailsService ervice 還依賴於WebSecurityConfig中提供的PasswordEncoder bean,但是為了提供一個UserDetailsService ervice 是必需的 - 這就是那個循環。

這表明設計中存在錯誤,應該以某種方式進行重構。

打破這個循環的最簡單方法是允許延遲注入PasswordEncoder ,方法是在UserDetailsServiceImpl erviceImpl class 中用@Lazy注釋它——但我不建議這樣做。 它會讓你擺脫這種情況,但糟糕的設計選擇不會得到糾正。

我建議將loadUserByUsername實現以外的所有邏輯從UserDetailsServiceImpl移到其他一些@Service (即UserService )中。 - 這樣你就會尊重 Spring 的UserDetailsService接口中定義的契約,並且你的UserDetailsServiceImpl將不會依賴於PasswordEncoder bean - 因此你的循環依賴將被刪除。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM