spring-security Web安全配置器适配器加载用户按用户名引发堆栈溢出错误

6ljaweal  于 2022-11-11  发布在  Spring
关注(0)|答案(1)|浏览(150)

我搜索了这个问题,但没有任何解决方案适合我。
所以我尝试在我的Sping Boot 应用程序中使用JWT标记。当我点击端点/登录时,我得到了WebSecurityConfigurerAdapter$UserDetailsServiceDelegator. loadUserByUsername抛出的StackOverflow错误。

一月一日

@ComponentScan("com.example.javaee_project.security")
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Bean
    @Override
    public UserDetailsService userDetailsServiceBean() throws Exception{
        return super.userDetailsServiceBean();
    }
    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoderBean() throws Exception{
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        super.configure(auth);
        auth.parentAuthenticationManager(authenticationManagerBean())
                .userDetailsService(userDetailsServiceBean())
                .passwordEncoder(bCryptPasswordEncoderBean());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable();
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        http.authorizeRequests().anyRequest().permitAll();
        http.addFilter(new CustomAuthenthicationFilter(authenticationManagerBean()));
    }

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

一个月一个月

public class CustomAuthenthicationFilter extends UsernamePasswordAuthenticationFilter {
    private final AuthenticationManager authenticationManager;

    public CustomAuthenthicationFilter(AuthenticationManager authenthicationManager){
        this.authenticationManager = authenthicationManager;
    }
    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);

        return authenticationManager.authenticate(authenticationToken);
    }

    @Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
        User user = (User) authResult.getPrincipal();
        Algorithm algorithm = Algorithm.HMAC256("secret".getBytes());
        String accessToken = JWT.create()
                .withSubject(user.getUsername())
                .withExpiresAt(new Date(System.currentTimeMillis() + 10*60*1000))
                .withIssuer(request.getRequestURL().toString())
                .withClaim("roles", user.getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList()))
                .sign(algorithm);

        response.setHeader("access_token", accessToken);
    }
}

应用程序使用者服务中的依使用者名称载入方法

@Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        AppUser user = appUserRepository.findByUsername(username);
        Collection<SimpleGrantedAuthority> authorities = new ArrayList<>();
        user.getRoles().forEach(role ->
                authorities.add(new SimpleGrantedAuthority(role.getName()))
        );
        if(user != null){
            log.info("null user");
            throw new UsernameNotFoundException("User not found");
        }
        return new User(user.getUsername(), user.getPassword(), authorities);
    }
}

主类

@SpringBootApplication(exclude = {SecurityAutoConfiguration.class})
@ComponentScan(basePackages = {"com.example.javaee_project.security"})
public class JavaEeProjectApplication {

    public static void main(String[] args) {
        SpringApplication.run(JavaEeProjectApplication.class, args);
    }

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

g6ll5ycj1#

因为当前AuthenticationManager父AuthenticationManager也委托当前AuthenticationManager
删除安全配置用户详细信息服务Bean()

@Bean
@Override
public UserDetailsService userDetailsServiceBean() throws Exception{
    return super.userDetailsServiceBean();
}

相关问题