有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

UserDetailsService中的java UserRepository为空

我使用的是Spring3.0.7,我在Spring secrutiy中通过UserDetailsService创建了bean。xml将其用作中的用户提供者

<authentication-manager>
    <authentication-provider user-service-ref='userDetailsService'>
        <password-encoder hash="sha"/>
    </authentication-provider>
</authentication-manager>

不幸的是,userRepository是空的,我不知道为什么,所以我在对其对象执行操作时得到了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

春季安全。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>

你能告诉我这里怎么了吗


共 (2) 个答案

  1. # 1 楼答案

    1. 选项:将@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);
            }
        }
    }
    
    1. 选项:使用构造函数更改服务XML声明。我假设UserRepositorybean名称是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"/>
    
  2. # 2 楼答案

    我必须使用组件扫描将context-param添加到context-xml中,现在所有bean都加载到config中

    <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>
                /WEB-INF/spring/webcontext/myServlet-context.xml
                /WEB-INF/application-security.xml
            </param-value>
        </context-param>