java - UserDetailsService 中的 UserRepository 为空
问题描述
我正在使用 Spring 3.0.7,并通过UserDetailsService
spring-secrutiy.xml 创建了 bean,以将其用作用户的提供者
<authentication-manager>
<authentication-provider user-service-ref='userDetailsService'>
<password-encoder hash="sha"/>
</authentication-provider>
</authentication-manager>
不幸的是, userRepository 是 null 我不知道为什么,所以我在对其对象执行操作时得到 NPE。
16-Dec-2020 21:20:16.700 SEVERE [http-nio-8080-exec-6] org.apache.catalina.core.StandardWrapperValve.invoke Servlet.service() for servlet [DispatcherServlet] in context with path [/fitnessapplication_war_exploded] threw exception
java.lang.NullPointerException
at main.configuration.UserDetailsServiceImpl.loadUserByUsername(UserDetailsServiceImpl.java:25)
at org.springframework.security.authentication.dao.DaoAuthenticationProvider.retrieveUser(DaoAuthenticationProvider.java:86)
at org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate(AbstractUserDetailsAuthenticationProvider.java:129)
at org.springframework.security.authentication.ProviderManager.doAuthentication(ProviderManager.java:130)
at org.springframework.security.authentication.AbstractAuthenticationManager.authenticate(AbstractAuthenticationManager.java:48)
at org.springframework.security.authentication.ProviderManager.doAuthentication(ProviderManager.java:148)
at org.springframework.security.authentication.AbstractAuthenticationManager.authenticate(AbstractAuthenticationManager.java:48)
at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:142)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
at org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter.doFilter(DefaultLoginPageGeneratingFilter.java:91)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:187)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:79)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:168)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:544)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:690)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:616)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:831)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1634)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
用户详情服务
package main.configuration;
import lombok.NoArgsConstructor;
import main.model.user.User;
import main.user.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
@Service
@NoArgsConstructor
public class UserDetailsServiceImpl implements UserDetailsService {
private UserRepository userRepository;
@Autowired
public UserDetailsServiceImpl(UserRepository userRepository) {
this.userRepository = userRepository;
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByUsername(username);
if (user != null) {
return user;
} else {
throw new UsernameNotFoundException("Not found: " + username);
}
}
}
在应用程序启动时,我将一些初始数据添加到 DB 中,因此必须创建 UserRepository 的 bean,但我不知道为什么它在 UserDetailsServiceImpl 中被视为 null。
Spring-security.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.0.3.xsd">
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/asd" access="permitAll"/>
<intercept-url pattern="/**" access="hasRole('ROLE_USER')"/>
<intercept-url pattern="/users" access="hasRole('ROLE_ADMIN')"/>
<http-basic/>
</http>
<beans:bean name="userDetailsService" class="main.configuration.UserDetailsServiceImpl"/>
<authentication-manager>
<authentication-provider user-service-ref='userDetailsService'>
<password-encoder hash="sha"/>
</authentication-provider>
</authentication-manager>
<beans:bean id="passwordEncoder" class="org.springframework.security.authentication.encoding.ShaPasswordEncoder">
<beans:constructor-arg value="256"/>
</beans:bean>
</beans:beans>
你能告诉我这里有什么问题吗?
解决方案
- 选项:将
@Autowired
注释放在userRepository
变量之前。
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByUsername(username);
if (user != null) {
return user;
} else {
throw new UsernameNotFoundException("Not found: " + username);
}
}
}
- 选项:使用构造函数更改服务 XML 声明。我假设
UserRepository
bean 名称是userRepository
.
<beans:bean name="userDetailsService" class="main.configuration.UserDetailsServiceImpl">
<constructor-arg index="0" ref="userRepository"/>
</beans:bean>
... 代替
<beans:bean name="userDetailsService" class="main.configuration.UserDetailsServiceImpl"/>
推荐阅读
- jquery - 添加 jQuery 移动库后,jQuery replaceWith 抛出错误
- templates - VueJS:外部模板文件(使用变量)
- listview - Flutter的ListView如何设置缓存大小?
- java - 将字符串值从一个函数传递到另一个函数而不将该字符串作为参数传递
- ios - 如何解析数据然后将其加载到pickerView中?
- javascript - 文件条目 API:何时完成?
- sql - 为什么我的查询没有按指定的列对数据进行分组?
- reactjs - 在反应中使用 Leaflet js 插件
- c++ - 哪些枚举值在 C++14 中是未定义的行为,为什么?
- angular6 - 我想根据复选框选择显示/隐藏 Angular 6 反应式表单组