gpt4 book ai didi

java - 无法自动连线字段: private org. springframework.security.core.userdetails.UserDetailsS​​ervice

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:11:58 25 4
gpt4 key购买 nike

我是Spring的新手,所以我一直在考虑安全方面。
每当我运行我的应用程序时,我都会得到:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'securityConfig': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.security.core.userdetails.UserDetailsService com.entirety.app.config.SecurityConfig.userDetailsServiceImplementation; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.security.core.userdetails.UserDetailsService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}



我已经很好地梳理了我的代码,无法查明问题所在。

Spring Framework版本:3.2.5.RELEASE
Spring 安全版本:3.2.0.M2

SecurityConfig.java
package com.entirety.app.config;

import com.entirety.app.service.implement.UserDetailsServiceImplementation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
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 javax.sql.DataSource;

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private DataSource dataSource;

@Autowired
private UserDetailsService userDetailsServiceImplementation;

@Override
protected void registerAuthentication(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication().dataSource(dataSource);
}

@Override
protected void configure(HttpSecurity http) throws Exception {
http.userDetailsService(userDetailsServiceImplementation)
.authorizeUrls()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/sec/**").hasRole("MODERATOR")
.antMatchers("/*").permitAll()
.anyRequest().anonymous().and().exceptionHandling().accessDeniedPage("/denied").and()
.formLogin()
.loginProcessingUrl("/j_spring_security_check")
.loginPage("/login")
.failureUrl("/error-login")
.and()
.logout()
.logoutUrl("/j_spring_security_logout")
.logoutSuccessUrl("/");
}

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

CrmUserService.java
@Service("userService")
@Transactional
public class CrmUserService implements UserDetailsService {
@Autowired
private UserDAO userDAO;

@Override
public UserDetails loadUserByUsername(String login) throws UsernameNotFoundException {

com.entirety.app.domain.User domainUser = userDAO.getUser(login);

boolean enabled = true;
boolean accountNonExpired = true;
boolean credentialsNonExpired = true;
boolean accountNonLocked = true;

return new User(
domainUser.getLogin(),
domainUser.getPassword(),
enabled,
accountNonExpired,
credentialsNonExpired,
accountNonLocked,
getAuthorities(domainUser.getAuthority().getId())
);
}

public Collection<? extends GrantedAuthority> getAuthorities(Integer role) {
List<GrantedAuthority> authList = getGrantedAuthorities(getRoles(role));
return authList;
}

public List<String> getRoles(Integer role) {

List<String> roles = new ArrayList<String>();

if (role.intValue() == 1) {
roles.add("ROLE_MODERATOR");
roles.add("ROLE_ADMIN");
} else if (role.intValue() == 2) {
roles.add("ROLE_MODERATOR");
}
return roles;
}

public static List<GrantedAuthority> getGrantedAuthorities(List<String> roles) {
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();

for (String role : roles) {
authorities.add(new SimpleGrantedAuthority(role));
}
return authorities;
}
}

没有逻辑上的原因导致它应该失败,但是它确实会失败。

笔记:

我的IDE可以链接 Autowiring 线(也就是说,它知道从何处进行 Autowiring 线以及所有内容),但是编译失败。

编辑2:
我已经从SecurityConfig.java文件中删除了以下代码
@Autowired
private UserDataService userDataService;

并将其添加到我所知道的POJO和 Controller 之一中,它会被定期调用并包含其他服务。
在这种情况下,将该代码粘贴到我的baseController.java文件中,该文件定向到呈现主页。
该服务已正确编译,我什至可以在 Controller 中调用它。

因此,问题仅被隔离到配置文件(例如SecurityConfig.java),这是唯一无法解决的问题。

编辑3:添加了额外的文件

SecurityInitializer.java
@Order(2)
public class SecurityInitializer extends AbstractSecurityWebApplicationInitializer {
}

WebInitializer.java
@Order(1)
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[] { PersistanceConfig.class, SecurityConfig.class }; //To change body of implemented methods use File | Settings | File Templates.
}

@Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[] { WebConfig.class };
}

@Override
protected String[] getServletMappings() {
return new String[] {"/"};
}

// @Override
// protected Filter[] getServletFilters() {
// CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
// characterEncodingFilter.setEncoding("UTF-8");
// return new Filter[] { characterEncodingFilter};
// }
}

mvc-dispatcher-servlet.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="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">

<context:component-scan base-package="com.entirety.app"/>

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".jsp"/>
</bean>

</beans>

web.xml
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

<display-name>Spring MVC Application</display-name>

<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>

最佳答案

更新(提供完整示例后)

看来您有多个问题。

web.xml与AbstractAnnotationConfigDispatcherServletInitializer

您创建的应用程序有一个web.xml,用于配置名为mvc-dispatcher的DispatcherServlet。 mvc-dispatcher具有mvc-dispatcher-servlet.xml的配置,该配置将com.springapp.sectest包中的所有bean都加载了。这意味着mvc-dispatcher可以找到您的UserDetailsService

该应用程序还具有AbstractAnnotationConfigDispatcherServletInitializer,它创建了一个DispatcherServlet来加载WebConfig Java配置。此DispatcherServlet无法看到mvc-dispatcher创建的任何Bean。

简而言之,您应该使用web.xml或DispatcherServlet配置AbstractAnnotationConfigDispatcherServletInitializer,而不要同时使用两者。

getRootConfigClasses与getServletConfigClasses

getRootConfigClasses中的任何配置通常称为根配置或父配置,并且无法查看getServletConfigClasses中定义的bean。 Spring Security使用由@EnableWebSecurity批注创建的名为springSecurityFilterChain的过滤器保护在getRootConfigClasses中定义的应用程序。这意味着通常最好将Spring Security的配置放在getRootConfigClasses中。对此有一些异常(exception),例如,如果您想在Spring MVC Controller 上进行方法安全性。

getServletConfigClasses中的任何配置通常称为子配置,并且可以查看在getRootConfigClasses中定义的bean。 getServletConfigClasses用于配置DispatcherServlet,并且必须包含用于Spring MVC的bean(即Controllers,ViewResovlers等)。在getRootConfigClasses中定义的任何Spring MVC bean都是可见的,但未使用。

此设置虽然有些困惑,但允许您使用隔离配置配置多个DispatcherServlet实例。实际上,很少有多个DispatcherServlet实例。

根据上述信息,您应该将UserDetailsService声明及其所有相关的Bean移至getRootConfigClasses。这将确保SecurityConfig.java可以找到UserDetailsService

拉请求修复

我已经提交了一份PR,以获取您的申请,以便它开始时没有错误https://github.com/worldcombined/AnnotateFailed/pull/1。一些注意事项

  • 该测试未使用父级和子级上下文,因此不反射(reflect)正在运行应用程序
  • 我必须移动资源文件夹,以便正确拾取
  • 我没有这样做,所以您实际上可以进行身份​​验证。没有login.jsp,并且您提供的UserDetailsS​​ervice始终返回null。相反,我尝试证明此处的错误已得到解决。

  • 原始答案

    基于此评论:

    @ComponentScan is undertaken in my mvc-dispatcher-servlet.xml as <context:component-scan base-package="com.entirety.app"/>



    看来您是在Dispatcher配置中而不是在根上下文中配置服务。

    Spring Security的配置通常是在根上下文中配置的。例如,可以扩展AbstractSecurityWebApplicationInitializer,如下所示:
    import org.springframework.security.web.context.*;

    public class SecurityWebApplicationInitializer
    extends AbstractSecurityWebApplicationInitializer {
    }

    您如何导入安全性配置?如果Spring Security配置在根上下文中,则它将看不到在Dispatcher Servlet上下文中定义的bean。

    解决方案是在根上下文中移动服务的配置,或将Spring Security配置移动到调度程序的ApplicationContext。例如,如果您的调度程序servlet被命名为mvc,那么将Spring Security配置移动到调度程序上下文中将如下所示。
    public class SecurityWebApplicationInitializer
    extends AbstractSecurityWebApplicationInitializer {
    protected String getDispatcherWebApplicationContextSuffix() {
    return "mvc";
    }
    }

    关于java - 无法自动连线字段: private org. springframework.security.core.userdetails.UserDetailsS​​ervice,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21526132/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com