[SPRING] autowire 필드를 사용할 수 없습니다 : private org.springframework.security.core.userdetails.UserDetailsService
SPRINGautowire 필드를 사용할 수 없습니다 : private org.springframework.security.core.userdetails.UserDetailsService
나는 봄에 익숙하지 않기 때문에 나는 사물의 보안 측면을 가지고 돌아 다녔다. 신청할 때마다 다음과 같이 처리됩니다.
내 코드를 잘 빗으로 훑어보고 문제를 정확하게 지적 할 수 없습니다.
Spring Framework 버전 : 3.2.5.RELEASE 봄 보안 버전 : 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는 autowire를 링크 할 수있다.
편집 2 : SecurityConfig.java 파일에서 다음 코드를 제거했습니다.
@Autowired
private UserDataService userDataService;
POJO 및 컨트롤러 중 하나에 추가했습니다. 정기적으로 호출되며 다른 서비스가 포함되어 있습니다. 이 경우 홈페이지를 렌더링하는 내 baseController.java 파일에 해당 코드를 붙여 넣습니다. 서비스가 제대로 컴파일되고 심지어 컨트롤러 내에서 호출 할 수 있습니다.
따라서 문제는 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-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>
해결법
-
==============================
1.여러 문제가있는 것 같습니다.
여러 문제가있는 것 같습니다.
만든 응용 프로그램에는 mvc-dispatcher라는 DispatcherServlet을 구성하는 web.xml이 있습니다. mvc-dispatcher에는 com.springapp.sectest 패키지 내의 모든 bean을로드하는 mvc-dispatcher-servlet.xml 구성이 있습니다. 즉, mvc-dispatcher가 UserDetailsService를 찾을 수 있습니다.
응용 프로그램에는 WebConfig Java 구성을로드 한 DispatcherServlet을 작성한 AbstractAnnotationConfigDispatcherServletInitializer도 있습니다. 이 DispatcherServlet은 mvc-dispatcher에 의해 생성 된 Bean을 볼 수 없습니다.
즉, web.xml 또는 AbstractAnnotationConfigDispatcherServletInitializer를 사용하여 DispatcherServlet을 구성하고 둘 다 구성하지 말아야합니다.
getRootConfigClasses 내의 모든 구성은 일반적으로 루트 또는 상위 구성이라고하며 getServletConfigClasses에 정의 된 Bean을 볼 수 없습니다. Spring Security는 @EnableWebSecurity 주석에 의해 생성 된 springSecurityFilterChain이라는 필터로 getRootConfigClasses에 정의 된 애플리케이션을 보호합니다. 즉, 일반적으로 getRootConfigClasses에 Spring Security 구성을 배치하는 것이 가장 좋습니다. Spring MVC 컨트롤러에서 메소드 보안을 수행하려는 경우와 같이 몇 가지 예외가 있습니다.
getServletConfigClasses 내의 모든 구성은 일반적으로 하위 구성이라고하며 getRootConfigClasses에 정의 된 Bean을 볼 수 있습니다. getServletConfigClasses는 DispatcherServlet을 구성하며 Spring MVC (즉, Controller, ViewResovler 등) 용 Bean을 포함해야합니다. getRootConfigClasses에 정의 된 모든 스프링 MVC 빈은 보이지만 사용되지는 않습니다.
이 설정은 조금 혼란 스럽지만 격리 된 구성으로 여러 DispatcherServlet 인스턴스를 가질 수 있습니다. 실제로 DispatcherServlet 인스턴스가 여러 개있는 것은 매우 드뭅니다.
위의 정보가 주어지면 UserDetailsService 선언을 모든 종속 Bean과 함께 getRootConfigClasses로 이동해야합니다. 이렇게하면 SecurityConfig.java가 UserDetailsService를 찾을 수 있습니다.
PR을 제출하여 오류없이 시작되도록 응용 프로그램을 얻으십시오. https://github.com/worldcombined/AnnotateFailed/pull/1. 몇 마디
이 의견을 바탕으로 :
루트 컨텍스트가 아닌 Dispatcher 구성 내에서 서비스를 구성하고있는 것 같습니다.
스프링 시큐러티의 구성은 일반적으로 루트 컨텍스트에서 구성됩니다. 예를 들어, 아래와 같이 AbstractSecurityWebApplicationInitializer를 확장 할 수 있습니다.
import org.springframework.security.web.context.*; public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer { }
보안 구성을 어떻게 가져오고 있습니까? 스프링 보안 구성이 루트 컨텍스트에 있으면 Dispatcher 서블릿 컨텍스트에 정의 된 bean을 볼 수 없습니다.
솔루션은 루트 컨텍스트에서 서비스 설정을 이동하거나 Spring 보안 설정을 디스패처의 ApplicationContext로 옮기는 것입니다. 예를 들어, Dispatcher 서블릿의 이름이 mvc 인 경우 Spring Security 구성을 Dispatcher 컨텍스트로 이동하면 다음과 같이 표시됩니다.
public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer { protected String getDispatcherWebApplicationContextSuffix() { return "mvc"; } }
-
==============================
2.SecurityConfig 클래스에 @ component 사용
SecurityConfig 클래스에 @ component 사용
-
==============================
3.그것은 유형에 의해 autowired해야하지만 ...
그것은 유형에 의해 autowired해야하지만 ...
UserDetailSservice의 이름을 지정했습니다.
@Service("userService")
너의 들판을 똑같이 이름 붙이려고해라.
@Autowired private UserDetailsService userService;
-
==============================
4.이 주석을 SecurityConfig 클래스에 추가하려고하면 어떻게 될까요?
이 주석을 SecurityConfig 클래스에 추가하려고하면 어떻게 될까요?
@ComponentScan (basePackages = "UserDetailsService가 포함 된 패키지")
from https://stackoverflow.com/questions/21526132/could-not-autowire-field-private-org-springframework-security-core-userdetails by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] 클래스 사용자 정의를 사용하여 파일 생성 충돌을 해결하는 방법 (0) | 2019.01.18 |
---|---|
[SPRING] MessageSource에서 메시지를 찾을 수 없습니다. (0) | 2019.01.18 |
[SPRING] 로그인하지 않고 스프링 웹 소켓 @SendToUser? (0) | 2019.01.17 |
[SPRING] 테스트 메소드 내에서 Spring 애플리케이션 컨텍스트를 다시로드하거나 새로 고칩니다. (0) | 2019.01.17 |
[SPRING] 스프링에서 동적으로 빈 참조를 설정하는 방법은? (0) | 2019.01.17 |