SpringBoot + Springboot-Security UserDetailsService中Service或者Dao 使用@Autowired注入爲NULL

版權聲明:本文爲CSDN博主「滔濤江水」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。

原文鏈接:https://blog.csdn.net/taotaojs/article/details/84955218

網上有一些關於這個問題的答案,但都不是基於SpringBoot的,一想到SpringBoot還要配置XML文件就頭大呀有木有。

 

以下就是解決方法:

在SecurityConfig中添加如下代碼
   

@Bean
    public UserDetailsService myUserService(){
        return new MyUserDetailsService();
    }


並且在configure(AuthenticationManagerBuilder auth)方法中將new MyUserService()改爲以上的方法名
   

 @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(myUserService());
    }


至此,自定義DetailsService中的Service就可以注入成功了。
另外,自定義DetailsService的@Service標註不需要也沒關係,因爲已經有@Bean標註了
說一下線索:

Spring Security在Spring加載完Bean之前就加載了(Spring框架中的Web.xml配置相關)
MyUserDetailsService繼承AbstractJUnit4SpringContextTests之後輸出applicationContext,發現applicationContext爲空,說明Spring沒有加載完成
Spring沒有掃描到MyUserDetailsService,否則@Service肯定能達到與@Bean同樣的效果
這個問題是相當冷門的,所以肯定有一個約定俗成的辦法,於是搜一下Spring Security詳細搭建就可以找到問題所在了

 

完整代碼,就是SpringSecurity配置類


@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{

    protected void configure(HttpSecurity http) throws Exception {
        http
                // 過濾請求
                .authorizeRequests()
                // 配置permitAll的不進行訪問控制!這裏的話是直接配置的是訪問首頁和訪問用戶信息,用戶分類,首頁輪播圖進行跳過
                .antMatchers("/image/**", "/index/**", "/goods-info/**", "/goods-category/**", "/carousel/**").permitAll()
                .antMatchers("/admin/**").hasAnyRole("ADMIN")   // 訪問用戶的角色必須要有ROLE_ADMIN角色才能進行訪問
                .antMatchers("/article/**").hasRole("USER")
                .anyRequest().authenticated()
                .and()
                .csrf().disable()
                .formLogin().disable()
                .sessionManagement().disable()
                .cors()
                .and()
                .headers().addHeaderWriter(new StaticHeadersWriter(Arrays.asList(
                new Header("Access-control-Allow-Origin","*"),
                new Header("Access-Control-Expose-Headers","Authorization"))))
                .and()
                // 過濾Options請求
                .addFilterAfter(new OptionsRequestFilter(), CorsFilter.class)
                .apply(new JsonLoginConfigurer<>()).loginSuccessHandler(jsonLoginSuccessHandler())
                .and()
                .apply(new JwtLoginConfigurer<>()).tokenValidSuccessHandler(jwtRefreshSuccessHandler()).permissiveRequestUrls("/logout")
                .and()
                .logout()
//		        .logoutUrl("/logout")   //默認就是"/logout"
                .addLogoutHandler(tokenClearLogoutHandler())
                .logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler())
                .and()
                .sessionManagement().disable();
    }

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

    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Bean("jwtUserService")
    protected JwtUserService jwtUserService() {
        return new JwtUserService();
    }

    @Bean("jwtAuthenticationProvider")
    protected AuthenticationProvider jwtAuthenticationProvider() {
        return new JwtAuthenticationProvider(jwtUserService());
    }

    @Bean("daoAuthenticationProvider")
    protected AuthenticationProvider daoAuthenticationProvider() throws Exception{
        //這裏會默認使用BCryptPasswordEncoder比對加密後的密碼,注意要跟createUser時保持一致
        DaoAuthenticationProvider daoProvider = new DaoAuthenticationProvider();
        daoProvider.setUserDetailsService(userDetailsService());
        return daoProvider;
    }

    @Override
    @Bean
    protected UserDetailsService userDetailsService() {
        return new JwtUserService();
    }

    @Bean
    protected JsonLoginSuccessHandler jsonLoginSuccessHandler() {
        return new JsonLoginSuccessHandler(jwtUserService());
    }

    @Bean
    protected JwtRefreshSuccessHandler jwtRefreshSuccessHandler() {
        return new JwtRefreshSuccessHandler(jwtUserService());
    }

    @Bean
    protected TokenClearLogoutHandler tokenClearLogoutHandler() {
        return new TokenClearLogoutHandler(jwtUserService());
    }

    @Bean
    protected CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Arrays.asList("*"));
        configuration.setAllowedMethods(Arrays.asList("GET","POST","HEAD", "OPTION"));
        configuration.setAllowedHeaders(Arrays.asList("*"));
        configuration.addExposedHeader("Authorization");
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }

}


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章