自定义 AuthenticationProvider ,UserDetailsService的实现类@Autowired 为null

项目场景:

整合spring security OAuth2自定义AuthenticationProvider 登录认证 签发token

问题描述:

在自定义 AuthenticationProvider 时 发现UserDetailsService 的实现类 UserService 一直注入不进去,为null

自定义 AuthenticationProvider 通过 username直接登录

package com.example.sso.provider;

import com.example.sso.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;

@Slf4j
public class UsernameAuthenticationProvider implements AuthenticationProvider {

    @Autowired
    UserService userService;

    public UsernameAuthenticationProvider() {
        log.info("UsernameAuthenticationProvider  loading......");
    }

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {

        String username = (String) authentication.getPrincipal();
        UserDetails user = userService.loadUserByUsername(username);
        if (null != user) {
            return new UsernamePasswordAuthenticationToken(user, authentication.getCredentials(), user.getAuthorities());
        }
        return null;
    }

    @Override
    public boolean supports(Class<?> authentication) {
         return authentication.equals(UsernamePasswordAuthenticationToken.class);
    }
}

解决办法,看最后三组代码
重写

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

在该配置类,注入UserDetailsService的实现类UserService,并将其设置到AuthenticationManagerBuilder 中。

然后将自定义的 UsernameAuthenticationProvider 在此实例化。然后将其注入到 AuthenticationManagerBuilder 中,他是用来管理所有的provider的

package com.example.sso.config;

import com.example.sso.provider.UsernameAuthenticationProvider;
import com.example.sso.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.BeanIds;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfigure extends WebSecurityConfigurerAdapter {

    //对外放开某些接口
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/login/getUser");
    }


    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable().authorizeRequests()
                .antMatchers("/**").authenticated().anyRequest().authenticated();//所有请求都需要验证

               // .anyRequest().permitAll(); //其他所有请求都不需要验证
    }

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

    @Bean(name = BeanIds.AUTHENTICATION_MANAGER)
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Autowired
    UserService userService;

    @Bean
    public UsernameAuthenticationProvider usernameAuthenticationProvider() {
        return new UsernameAuthenticationProvider();
    }

    //添加自定义的provider
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(usernameAuthenticationProvider());
        auth.userDetailsService(userService);
    }

}

解释一下这段代码 @Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private UserDetailsService userDetailsService; @Autowired private LoginSuccessHandler loginSuccessHandler; @Bean public BCryptPasswordEncoder bCryptPasswordEncoder(){ return new BCryptPasswordEncoder(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { //配置自定义登录逻辑 auth.userDetailsService(userDetailsService); } @Override protected void configure(HttpSecurity http) throws Exception { //配置放行url http.authorizeRequests() .antMatchers("/swagger-ui.html","/swagger-resources/**","/webjars/**","/*/api-docs" ,"/login","/logout").permitAll() .anyRequest().authenticated() //配置其它url要验证 .and() .formLogin() //配置登录相关 .successHandler(loginSuccessHandler) //配置登录成功的处理器 .failureHandler((req,resp,auth) -> { //配置登录失败的处理器 ResponseResult.write(resp, ResponseResult.error(ResponseStatus.LOGIN_ERROR)); }) .and() .exceptionHandling() .authenticationEntryPoint((req,resp,auth) ->{ //配置拦截未登录请求的处理 ResponseResult.write(resp,ResponseResult.error(ResponseStatus.AUTHENTICATE_ERROR)); }) .and() .logout() .logoutSuccessHandler((req,resp,auth) ->{ //配置登出处理器 ResponseResult.write(resp,ResponseResult.ok("注销成功")); }) .clearAuthentication(true) //清除验证缓存 .and() .csrf() .disable() //关闭csrf保护 .sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.STATELESS); //不使用session } }
07-13
这段代码是一个Spring Security的配置,用于配置安全相关的设置。下面是对代码中的主要部分进行解释: 1. @Configuration:该注解表示这是一个配置。 2. extends WebSecurityConfigurerAdapter:通过继承WebSecurityConfigurerAdapter,可以方便地配置Spring Security相关的设置。 3. @Autowired:通过@Autowired注解,将所需的依赖注入到配置中。 4. BCryptPasswordEncoder:通过@Bean注解,创建一个BCryptPasswordEncoder实例,用于密码加密。 5. configure(AuthenticationManagerBuilder auth):重写该方法,配置自定义的登录逻辑。在这里,通过调用auth.userDetailsService(userDetailsService),将自定义UserDetailsService注入到AuthenticationManagerBuilder中。 6. configure(HttpSecurity http):重写该方法,配置请求的权限、登录相关、异常处理、登出等。 - authorizeRequests():指定需要进行权限验证的请求。 - antMatchers().permitAll():配置允许访问的URL,这里配置了一些Swagger相关的URL和登录、登出URL。 - anyRequest().authenticated():配置其他URL需要进行身份验证。 - formLogin():配置表单登录相关设置。 - successHandler():配置登录成功的处理器。 - failureHandler():配置登录失败的处理器。 - exceptionHandling():配置异常处理。 - authenticationEntryPoint():配置拦截未登录请求的处理。 - logout():配置登出相关设置。 - logoutSuccessHandler():配置登出成功的处理器。 - clearAuthentication(true):清除验证缓存。 - csrf().disable():关闭CSRF保护。 - sessionCreationPolicy():配置不使用session。 该配置主要是为了实现对URL的权限控制、登录验证、异常处理和登出等功能的设置。根据具体的业务需求,可以根据这个基础配置进行修改和扩展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值