情况一:Please ensure you have configured authentication.
错误信息内容:
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.security.authentication.AuthenticationManager]: Factory method 'authenticationManagerBean' threw exception; nested exception is org.springframework.beans.FatalBeanException: A dependency cycle was detected when trying to resolve the AuthenticationManager. Please ensure you have configured authentication.
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185)
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:651)
... 33 common frames omitted
Caused by: org.springframework.beans.FatalBeanException: A dependency cycle was detected when trying to resolve the AuthenticationManager. Please ensure you have configured authentication.
错误信息截图:
情况二:authenticationManager cannot be null
错误信息内容:
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.yunbu.oa.security.filters.JwtAuthenticationFilter]: Factory method 'jwtAuthenticationFilter' threw exception; nested exception is java.lang.IllegalArgumentException: authenticationManager cannot be null
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185) ~[spring-beans-5.3.12.jar:5.3.12]
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:653) ~[spring-beans-5.3.12.jar:5.3.12]
... 61 common frames omitted
Caused by: java.lang.IllegalArgumentException: authenticationManager cannot be null
at org.springframework.util.Assert.notNull(Assert.java:201) ~[spring-core-5.3.12.jar:5.3.12]
at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.<init>(BasicAuthenticationFilter.java:112) ~[spring-security-web-5.5.3.jar:5.5.3]
at com.yunbu.oa.security.filters.JwtAuthenticationFilter.<init>(JwtAuthenticationFilter.java:46) ~[classes/:na]
at com.yunbu.oa.security.config.WebSecurityConfig.jwtAuthenticationFilter(WebSecurityConfig.java:80) ~[classes/:na]
at com.yunbu.oa.security.config.WebSecurityConfig$$EnhancerBySpringCGLIB$$2666cc62.CGLIB$jwtAuthenticationFilter$3(<generated>) ~[classes/:na]
at com.yunbu.oa.security.config.WebSecurityConfig$$EnhancerBySpringCGLIB$$2666cc62$$FastClassBySpringCGLIB$$580c6847.invoke(<generated>) ~[classes/:na]
错误信息截图:
我出现的原因是在WebSecurityConfig中。也就是继承WebSecurityConfigurerAdapter抽象类的类。
解决办法:
在上述类(WebSecurityConfig.java)中添加如下代码:
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService())
.passwordEncoder(passwordEncoder());
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
完整代码展示:
package com.abliner.oa.security.config;
import com.abliner.oa.security.filters.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import java.util.List;
/**
* @des: security核心配置
* @author: abliner
* @date: 2023-11-10
*/
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private SecurityProperties securityProperties;
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
List<String> ignoreUrls = securityProperties.getIgnoreUrls();
String[] ignores = null;
if (null != ignoreUrls && ignoreUrls.size() > 0) {
ignores = new String[ignoreUrls.size()];
for (int i = 0; i < ignoreUrls.size(); i++) {
ignores[i] = ignoreUrls.get(i);
}
}
httpSecurity
// 禁用csrf
.csrf().disable()
.exceptionHandling()
.authenticationEntryPoint(noAuthenticationEntryPoint())
.accessDeniedHandler(sysAccessDeniedHandler())
// 防止iframe跨域
.and()
.headers().frameOptions().disable()
// 不创建会话
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
// 认证配置
.and().authorizeRequests()
// 过滤登录请求
.antMatchers(ignores).permitAll()
// 所有请求都需要认证
.anyRequest().authenticated()
.and()
.exceptionHandling()
.accessDeniedHandler(restfulAccessDeniedHandler())
.authenticationEntryPoint(restAuthenticationEntryPoint())
.and()
.addFilter(jwtAuthenticationFilter());
}
@Bean
public NoAuthenticationEntryPoint noAuthenticationEntryPoint() {
return new NoAuthenticationEntryPoint();
}
@Bean
public SysAccessDeniedHandler sysAccessDeniedHandler() {
return new SysAccessDeniedHandler();
}
@Bean
public JwtAuthenticationFilter jwtAuthenticationFilter() throws Exception {
return new JwtAuthenticationFilter(authenticationManager());
}
@Bean
public RestfulAccessDeniedHandler restfulAccessDeniedHandler() {
return new RestfulAccessDeniedHandler();
}
@Bean
public RestAuthenticationEntryPoint restAuthenticationEntryPoint() {
return new RestAuthenticationEntryPoint();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService())
.passwordEncoder(passwordEncoder());
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
SecurityProperties这个是我的配置文件,是用来过滤访问白名单的,跟本节内容无关。