Java 设置 bean 属性“userDetailsS​​ervice”时无法解析对 bean 的引用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/43005162/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 00:35:36  来源:igfitidea点击:

Cannot resolve reference to bean while setting bean property 'userDetailsService'

javasolrspring-security

提问by B.J. A.A.

I'm doing my own custom security with Spring Security and a solr core, it seems like I did something wrong but I'm not sure what.

我正在使用 Spring Security 和 solr 核心做我自己的自定义安全性,似乎我做错了什么,但我不确定是什么。

Stack trace:

堆栈跟踪:

Caused by: java.lang.RuntimeException: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.filterChains': Cannot resolve reference to bean 'org.springframework.security.web.DefaultSecurityFilterChain#0' while setting bean property 'sourceList' with key [0]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.web.DefaultSecurityFilterChain#0': Cannot resolve reference to bean 'org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter#0' while setting constructor argument with key [5]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter#0': Cannot resolve reference to bean 'org.springframework.security.authentication.ProviderManager#0' while setting bean property 'authenticationManager'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.authentication.ProviderManager#0': Cannot resolve reference to bean 'authenticationManager' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.authenticationManager': Cannot resolve reference to bean 'org.springframework.security.authentication.dao.DaoAuthenticationProvider#0' while setting constructor argument with key [0]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.authentication.dao.DaoAuthenticationProvider#0': Cannot resolve reference to bean while setting bean property 'userDetailsService'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'CustomUserDetails' is defined
    at io.undertow.servlet.core.DeploymentManagerImpl.deploy(DeploymentManagerImpl.java:231)
    at org.wildfly.extension.undertow.deployment.UndertowDeploymentService.startContext(UndertowDeploymentService.java:100)
    at org.wildfly.extension.undertow.deployment.UndertowDeploymentService.run(UndertowDeploymentService.java:82)

This the security-context.xmlfile:

这是security-context.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:security="http://www.springframework.org/schema/security"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
        http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-4.0.xsd">

    <security:global-method-security
        secured-annotations="enabled"></security:global-method-security>
    <security:http auto-config="true" realm="Protected Web"
        pattern="/**" authentication-manager-ref="authenticationManager">
        <security:csrf disabled="true" />

        <security:intercept-url pattern="/index/**" access="hasAnyRole('ROLE_ADMIN','ROLE_USER')" />

        <security:intercept-url pattern="/rest/api/1.0/**" access="isAuthenticated()" />

        <security:intercept-url pattern="/**" access="permitAll" />

        <security:form-login login-page="/login"
            username-parameter="j_username" login-processing-url="/j_spring_security_check"
            password-parameter="j_password" authentication-failure-url="/login?error=1"
            default-target-url="/index" always-use-default-target="true" />

        <security:logout invalidate-session="true"
            delete-cookies="true" logout-url="/j_spring_security_logout"
            logout-success-url="/login" />
        <security:session-management>
            <security:concurrency-control
                max-sessions="2" />
        </security:session-management>
    </security:http>



       <security:authentication-manager alias="authenticationManager">
        <security:authentication-provider user-service-ref="CustomUserDetails" />
    </security:authentication-manager>

</beans>

The class CustomUserDetails:

班级CustomUserDetails

@Service
public class CustomUserDetails implements UserDetailsService {

    private static final Logger logger = Logger.getLogger(StatusAppJob.class);

    @Autowired
    private UserAppRepository userAppRepository;

    @Override
    public UserDetails loadUserByUsername(final String username) throws UsernameNotFoundException {

        List<UsuarioApp> result =  getUserDetails(username);

        if(!result.isEmpty())
        {

        }
        else{
            throw new UsernameNotFoundException(username + " not found");
        }

        UserDetails user = new User(username, result.get(0).getPassword(), true, true, true, true, getAuthorities(result.get(0).getRol()));
             return user;

    }

    public Collection<? extends GrantedAuthority> getAuthorities(String rol) {
        List<SimpleGrantedAuthority> auths = new java.util.ArrayList<SimpleGrantedAuthority>();
        auths.add(new SimpleGrantedAuthority(rol));
        return auths;
    }

    public List<UsuarioApp> getUserDetails(String user) {
        // TODO Auto-generated method stub

        return userAppRepository.findUser(user);
    }

}

The app-context.xmlfile:

app-context.xml文件:

    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
    http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
        id="WebApp_ID" version="3.0">
        <display-name>secturv2</display-name>

        <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>
                /WEB-INF/solr-config.xml,
                /WEB-INF/Spring-Quartz.xml,
                /WEB-INF/spring/security-context.xml,
                /WEB-INF/spring/postgres-config.xml  

            </param-value>
        </context-param>
    <!--,   /WEB-INF/spring/postgres-config.xml  -->
        <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
        <listener>
            <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
        </listener>

        <servlet>
            <servlet-name>dispatcher</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
            </init-param>
            <load-on-startup>1</load-on-startup>
        </servlet>

        <servlet-mapping>
            <servlet-name>dispatcher</servlet-name>
            <url-pattern>/</url-pattern>
        </servlet-mapping>

        <servlet-mapping>
            <servlet-name>jsp</servlet-name>
            <url-pattern>*.html</url-pattern>
        </servlet-mapping>

        <!-- Spring Security -->
        <filter>
            <filter-name>springSecurityFilterChain</filter-name>
            <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
        </filter>

        <filter-mapping>
            <filter-name>springSecurityFilterChain</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>

    <!--    Sesiones de Hibernate -->
        <filter>
            <filter-name>OpenSessionInViewFilter</filter-name>
            <filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>
            <init-param>
                <param-name>sessionFactoryBeanName</param-name>
                <param-value>sfTurismo</param-value>
            </init-param>
        </filter>
        <filter-mapping>
            <filter-name>OpenSessionInViewFilter</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>

        <error-page>
            <error-code>401</error-code>
            <location>/error</location>
        </error-page>

        <error-page>
            <error-code>403</error-code>
            <location>/error</location>
        </error-page>

        <error-page>
            <error-code>500</error-code>
            <location>/error</location>
        </error-page>

    </web-app>

EDIT:

编辑:

Added the servlet-context.xmlfile:

添加了servlet-context.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <annotation-driven />
    <context:component-scan base-package="mx.sectur.turismo" />
    <!-- Handles HTTP GET requests for /resources/** by efficiently serving 
        up static resources in the ${webappRoot}/resources directory -->
    <resources mapping="/resources/**" location="/resources/" />
    <resources location="/views/" mapping="/**" />

    <beans:bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean" />

    <beans:bean
        class="org.springframework.data.repository.support.DomainClassConverter">
        <beans:constructor-arg ref="conversionService" />
    </beans:bean>

    <mvc:annotation-driven conversion-service="conversionService">
        <mvc:argument-resolvers>
            <beans:bean
                class="org.springframework.data.web.PageableHandlerMethodArgumentResolver">
                <beans:property name="maxPageSize" value="10"></beans:property>
            </beans:bean>
        </mvc:argument-resolvers>
    </mvc:annotation-driven>

    <beans:bean
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <beans:property name="prefix" value="/views/" />
        <beans:property name="suffix" value=".jsp" />
    </beans:bean>

    <interceptors>
        <beans:bean id="webContentInterceptor"
            class="org.springframework.web.servlet.mvc.WebContentInterceptor">
            <beans:property name="cacheSeconds" value="0" />
            <beans:property name="useExpiresHeader" value="true" />
            <beans:property name="useCacheControlHeader" value="true" />
            <beans:property name="useCacheControlNoStore" value="true" />
        </beans:bean>
    </interceptors>

</beans:beans>

Why I'm getting

为什么我得到

Cannot resolve reference to bean while setting bean property 'userDetailsService'"

设置 bean 属性“userDetailsS​​ervice”时无法解析对 bean 的引用”

message?

信息?

采纳答案by Dhiraj

These issue is due to referencing bean using wrong name.

这些问题是由于使用错误的名称引用 bean 造成的。

Please override the name of the bean created by @Service annotation like this

请像这样覆盖@Service注解创建的bean名称

@Service("CustomUserDetails")
public class CustomUserDetails implements UserDetailsService 

By default, Spring will lower case the first character of the component – from ‘CustomUserDetails' to ‘customUserDetails'. And you can retrieve this component with name ‘customUserDetails'.

默认情况下,Spring 将小写组件的第一个字符——从 'CustomUserDetails' 到 'customUserDetails'。您可以使用名称“customUserDetails”检索此组件。

so you can also modify below code if you do not want to override default name as below

所以如果你不想覆盖默认名称,你也可以修改下面的代码

 <security:authentication-manager alias="authenticationManager">
        <security:authentication-provider user-service-ref="customUserDetails" />
    </security:authentication-manager>

Please refer thislink for better understanding this concept

请参考链接以更好地理解此概念

Other thing that might be causing issue is you have defined annotation driven in servelet-xml which is in web application context where your service bean is getting initialized. but you have defined security-context in main application context. hence just create a file give any name to it and shift to that file.

可能导致问题的另一件事是您已经定义了在 servelet-xml 中驱动的注释,它位于您的服务 bean 正在初始化的 Web 应用程序上下文中。但是您已经在主应用程序上下文中定义了安全上下文。因此只需创建一个文件,为其命名并转移到该文件。

回答by nazia

I'm new to Spring but looks like your spring application-context file needs something like this-

我是 Spring 的新手,但看起来您的 Spring 应用程序上下文文件需要这样的东西-

<bean id="userDetailsService" class="com.package.CustomUserDetails "/>

回答by enator

I had a similar problem once.

我曾经遇到过类似的问题。

The application-context file should be present in the resources folder in order for the ClassPathXmlApplicationContext to load the context config file.

应用程序上下文文件应存在于资源文件夹中,以便 ClassPathXmlApplicationContext 加载上下文配置文件。

回答by Gani

The class path resource of you bean is wrong or the file name is not properly mentioned. In your case you have not mentioned the bean name and spring context is unable to autodetect it and get this instance from the context.

你 bean 的类路径资源错误或文件名没有正确提及。在您的情况下,您没有提到 bean 名称,并且 spring 上下文无法自动检测它并从上下文中获取此实例。

There are two ways to do this

有两种方法可以做到这一点

  1. With Annotation
  1. 带注释

Use @service on top of the class which is used to auto detect the class like

在类的顶部使用 @service 用于自动检测类

@Service("BeanName") // so that spring context can autodetect it and we can get its instance from the context
class className{
//class members
//constructors
//methods
}
  1. With XML
  1. 使用 XML

Mention bean class properly

正确提及 bean 类

<bean id="1" class="com.package.javafilename"></bean>