Estoy perplejo con SpringSecurity. Hay muchas maneras de implementar una cosa simple y mezclé todo.

Mi código es el siguiente pero lanza la excepción. Si puedo quitar UserDetailsService relacionados con los códigos, la aplicación se ejecuta y puedo iniciar sesión in-memory los usuarios. Como se sugiere a continuación, me he convertido la configuración basado en XML, pero los usuarios no pueden iniciar sesión.

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:  
org.springframework.security.core.userdetails.UserDetailsService 
com.myproj.config.SecurityConfig.userDetailsService; 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),  
@org.springframework.beans.factory.annotation.Qualifier(value=userDetailsService)}
Caused by: org.springframework.beans.factory.BeanCreationException: Could not 
autowire field 
org.springframework.security.core.userdetails.UserDetailsService 
com.myproj.config.SecurityConfig.userDetailsService; 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), 
@org.springframework.beans.factory.annotation.Qualifier(value=userDetailsService)}
Caused by: 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), 
@org.springframework.beans.factory.annotation.Qualifier(value=userDetailsService)}

Web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<listener>
<listener-class>org.apache.tiles.extras.complete.CompleteAutoloadTilesListener</listener-class>
</listener>
<servlet>
<servlet-name>proj</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>proj</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>

MvcWebApplicationInitializer

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class MvcWebApplicationInitializer
extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { SecurityConfig.class };
}
@Override
protected Class<?>[] getServletConfigClasses() {
return null;
}
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}

SecurityWebApplicationInitializer

import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
public class SecurityWebApplicationInitializer
extends AbstractSecurityWebApplicationInitializer {
}

SecurityConfig

@Configuration
@EnableWebMvcSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
@Qualifier("userDetailsService")
UserDetailsService userDetailsService;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth)
throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(
passwordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/resources/**", "/", "/index", "/aboutus")
.permitAll()
.antMatchers("/profile/**")
.hasRole("USER")
.and()
.formLogin().loginPage("/signin").failureUrl("/signin?error")
.permitAll().and().logout().logoutUrl("/signout").permitAll();
}
@Bean
public PasswordEncoder passwordEncoder() {
PasswordEncoder encoder = new BCryptPasswordEncoder();
return encoder;
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception        
{
return super.authenticationManagerBean();
}
}

MemberServiceImpl

@Service("userDetailsService")
public class MemberServiceImpl implements UserDetailsService {
@Autowired
MemberRepository memberRepository;
private List<GrantedAuthority> buildUserAuthority(String role) {
Set<GrantedAuthority> setAuths = new HashSet<GrantedAuthority>();
setAuths.add(new SimpleGrantedAuthority(role));
List<GrantedAuthority> result = new ArrayList<GrantedAuthority>(
setAuths);
return result;
}
private User buildUserForAuthentication(Member member,
List<GrantedAuthority> authorities) {
return new User(member.getEmail(), member.getPassword(),
member.isEnabled(), true, true, true, authorities);
}
@Override
@Transactional(readOnly = true)
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException {
Member member = memberRepository.findByUserName(username);
List<GrantedAuthority> authorities = buildUserAuthority("Role");
return buildUserForAuthentication(member, authorities);
}
}

Actualización de 1

Incluso después de añadir la siguiente anotación, y authenticationManagerBean método de SecurityConfig la misma excepción es lanzada.

    @EnableGlobalMethodSecurity(prePostEnabled = true)

Actualización 2

Como se sugiere en una de las respuestas, me convierte a XML de configuración basada en el actual código es el siguiente;sin embargo, cuando presente el formulario de login no hacer nada.

Spring-Security.xml

<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.xsd">
<beans:import resource='login-service.xml' />
<http auto-config="true" access-denied-page="/notFound.jsp"
use-expressions="true">
<intercept-url pattern="/" access="permitAll" />
<form-login login-page="/signin" authentication-failure-url="/signin?error=1"
default-target-url="/index" />
<remember-me />
<logout logout-success-url="/index.jsp" />
</http>
<authentication-manager>
<authentication-provider>
<!-- <user-service> <user name="admin" password="secret" authorities="ROLE_ADMIN"/> 
<user name="user" password="secret" authorities="ROLE_USER"/> </user-service> -->
<jdbc-user-service data-source-ref="dataSource"
users-by-username-query="
select username,password,enabled 
from Member where username=?"
authorities-by-username-query="
select username 
from Member where username = ?" />
</authentication-provider>
</authentication-manager>
</beans:beans>

login-service.xml

<beans xmlns="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">
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost/testProject" />
<property name="username" value="root" />
<property name="password" value="" />
</bean>
</beans>
  • Por un lado dices que quieres Primavera-seguridad para recuperar a los usuarios de DB, y por el otro lado usted dice y cito » necesito tener acceso a los usuarios en la base de datos usando Hibernate.’.. Cuál exactamente es? Y el código parece estar bien para el inicio de sesión. ¿Qué son exactamente tratando de sacar fuera de aquí?
  • la pregunta se reformula. Estoy usando la primavera de la seguridad y la necesito para leer los detalles de los usuarios de la bd. Mi ORM aquí es de hibernación.
  • ¿Cómo estás recogiendo el @Service anotación en MemberServiceImpl? Normalmente habría que agregar una @ComponentScan anotación elige eso. Si ha agregado que, por favor, incluya todos los nombres de los paquetes para la configuración con @ComponentScan y para MemberServiceImpl.
  • Intente esto : sivalabs.in/2014/03/springmvc4-spring-data-jpa.html
  • que tutorial hecho demasiado complicado. ¿Sabes de alguno mejor?
  • para tu pregunta.. si necesitas más ayuda comentario sobre mí.
  • ¿Quieres mi código en github..voy a subir
  • Yo muy agradecidos si usted podría compartir un enlace.
  • Ok..Aquí está el enlace. Tenemos un proyecto descargable también. Cualquier error y la duda comentario en mi..dineshonjava.com/2013/02/… .
  • Todos los requisitos de base de datos están en ese mismo enlace
  • apreciar que comprobar que fuera.
  • Aquí puede descargar el ramo de la Primavera de seguridad de los archivos jar. No uso diferente de la versión de los archivos jar de la primavera y la primavera de seguridad..usar la misma versión.. u puede descargar aquí..maven.springframework.org/release/org/springframework/security
  • lo siento se me olvidaba, yo le dará una recompensa de 200 así si se soluciona mi problema.
  • Seguir comentando sobre mí.. voy a resolver sus problemas
  • hey comentario en mí si tienes alguna duda.. solo 14hrs izquierda
  • Todavía estoy cableado hasta. ¿Qué entiende usted por 14hrs a la izquierda?
  • eso es la recompensa final del tiempo
  • no te preocupes por eso, si su solución resuelve mi problema, voy a ofrecer otra recompensa 🙂
  • No hay necesidad de cambiar a xml. Configuración de Java se ve mucho mejor, el cambio a xml sólo para resolver un problema es una tontería y un indicador de que usted no tiene idea de lo que estás haciendo. Entonces, ¿conseguir su problema resuelto todavía? Veo algunas buenas respuestas aquí, pero actualmente estoy en el móvil, si no es resuelto por la mañana voy a publicar un ejemplo de trabajo. La buena suerte.
  • gracias por tu comentario, me cambié a xml-basado en la esperanza de resolver el problema más rápido, ya que estoy tratando con él por un largo tiempo ahora, también, yo solía trabajar con XML en base a la seguridad el año pasado, pero casi se me olvida muchas partes de ella. Pensé que podría recordar todo, pero no todavía.; sin embargo, todavía estoy teniendo problemas diferentes. Yo no podría encontrar un ejemplo de trabajo!!!, y me vuelve loco. Sería muy apreciado si usted me diera un ejemplo de trabajo, así que puedo comprender cómo es que funciona y lo que yo estaba haciendo mal! Parece casi un 19 personas están buscando el mismo resultado.
  • No estoy seguro acerca de exactamente el problema que están enfrentando ahora, pero trate de agregar el número de puerto en la base de datos de URL. Cambio jdbc:mysql://localhost/testProject a jdbc:mysql://localhost:3306/testProject (o cualquier puerto en el que se ejecuta la aplicación).

9 Comentarios

  1. 19

    Creo que te olvides de añadir esta anotación en SecurityConfig Clase

    @Configuration
    @EnableWebMvcSecurity
    @EnableGlobalMethodSecurity(prePostEnabled = true)
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    @Qualifier("userDetailsService")
    UserDetailsService userDetailsService;
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth)
    throws Exception {
    auth.userDetailsService(userDetailsService).passwordEncoder(
    passwordEncoder());
    }
    @Override
    protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
    .antMatchers("/resources/**", "/", "/index", "/aboutus")
    .permitAll().antMatchers("/profile/**").hasRole("USER").and()
    .formLogin().loginPage("/signin").failureUrl("/signin?error")
    .permitAll().and().logout().logoutUrl("/signout").permitAll();
    }
    @Bean
    public PasswordEncoder passwordEncoder() {
    PasswordEncoder encoder = new BCryptPasswordEncoder();
    return encoder;
    }
    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
    return super.authenticationManagerBean();
    }
    }

    y una cosas más, yo pienso que este grano no es necesario

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

    Por favor, intente esto espero que esto funcionará para usted..

    Para obtener usuario actual

    public String getUsername() {
    SecurityContext context = SecurityContextHolder.getContext();
    Authentication authentication = context.getAuthentication();
    if (authentication == null)
    return null;
    Object principal = authentication.getPrincipal();
    if (principal instanceof UserDetails) {
    return ((UserDetails) principal).getUsername();
    } else {
    return principal.toString();
    }
    }
    public User getCurrentUser() {
    if (overridenCurrentUser != null) {
    return overridenCurrentUser;
    }
    User user = userRepository.findByUsername(getUsername());
    if (user == null)
    return user;
    }

    Gracias

    • Gracias, sería grande si usted podría añadir algunas explicaciones a su respuesta para mí para entender mejor el código.
    • Seguro,mediante el uso de @EnableGlobalMethodSecurity fácilmente podemos garantizar nuestros métodos de configuración de Java. Tenga en cuenta que methodSecurityService no es realmente parte de nuestra configuración de Seguridad, pero debemos crear nuestro MethodSecurityService mediante Resorte de modo que se puede tener Seguridad que se aplica a ella.
    • Si usted desea conseguir un actual usuario de inicio de sesión de spring security, a continuación, utilizar este método .Tengo la actualización de nuestra respuesta
    • He añadido que la anotación, pero todavía se lanza la misma excepción.
    • han de quitar authenticationManagerBean bean?
    • sí, lo hice, a continuación, limpiar el proyecto y corrió otra vez.

  2. 15

    Creo que el problema podría ser debido a la falta de @ComponentScan anotación. Cuando tratando de autowire userDetailsService en SecurityConfig, no es capaz de encontrar un adecuado bean para autowire con.

    Un resorte aplicación, normalmente se ha separado un «contexto de aplicación», además de mvc «contexto», «contexto de seguridad» (que ya tiene a través de SecurityConfig), etc.

    No estoy seguro si poner @ComponentScan en SecurityConfig sí va a trabajar en no, pero usted puede darle una oportunidad:

    @Configuration
    @ComponentScan("your_base_package_name_here")
    @EnableWebMvcSecurity
    @EnableGlobalMethodSecurity(prePostEnabled = true)
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
    ...
    }

    Reemplazar «your_base_package_name_here» con el nombre del paquete que contiene su @Component o @Service clases.

    Si esto no funciona, añadir una nueva clase vacía con @ComponentScan anotación:

    @Configuration
    @ComponentScan("your_base_package_name_here")
    public class AppConfig {
    //Blank
    }

    Fuente: http://docs.spring.io/spring-javaconfig/docs/1.0.0.M4/reference/html/ch06s02.html

  3. 6

    Ver que hay algunos errores que existen en su base de código de intentar resolverlo por ver el código de abajo.

    Quitar su SecurityConfig archivo y convertir en archivo xml de configuración basada en.

    Su spring-security.xml debe parecerse a esto.

       <security:http auto-config="true" >  
    <security:intercept-url pattern="/index*" access="ROLE_USER" />  
    <security:form-login login-page="/login" default-target-url="/index"  
    authentication-failure-url="/fail2login" />  
    <security:logout logout-success-url="/logout" />  
    </security:http>  
    <security:authentication-manager>  
    <security:authentication-provider>  
    <!-- <security:user-service>  
    <security:user name="samplename" password="sweety" authorities="ROLE_USER" />  
    </security:user-service> -->  
    <security:jdbc-user-service data-source-ref="dataSource"    
    users-by-username-query="select username, password, active from users where username=?"   
    authorities-by-username-query="select us.username, ur.authority from users us, user_roles ur   
    where us.user_id = ur.user_id and us.username =?  "   
    />  
    </security:authentication-provider>  
    </security:authentication-manager>  

    web.xml debe ser como este:

     <servlet>  
    <servlet-name>sdnext</servlet-name>  
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
    <load-on-startup>1</load-on-startup>  
    </servlet>  
    <servlet-mapping>  
    <servlet-name>sdnext</servlet-name>  
    <url-pattern>/</url-pattern>  
    </servlet-mapping>  
    <listener>  
    <listener-class>  
    org.springframework.web.context.ContextLoaderListener  
    </listener-class>  
    </listener>  
    <context-param>  
    <param-name>contextConfigLocation</param-name>  
    <param-value>  
    /WEB-INF/sdnext-*.xml,  
    </param-value>  
    </context-param>  
    <welcome-file-list>  
    <welcome-file>index</welcome-file>  
    </welcome-file-list>  
    <!-- 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>  
  4. 3

    Trate de añadir el siguiente método para su SecurityConfig:

    @Bean
    public UserDetailsService userDetailsServiceBean() throws Exception {
    return super.userDetailsServiceBean();
    }
  5. 2

    Que las costuras que su «userDetailsService» bean es declarado @Autowired, pero no está disponible como una clase (MemberServiceImpl) en el contexto de su SecurityConfig.

    Supongo que en su MvcWebApplicationInitializer debe incluir MemberServiceImpl también como:

    @Override
    protected Class<?>[] getRootConfigClasses() {
    return new Class[] { SecurityConfig.class, MemberServiceImpl.class };
    }
  6. 1

    Aquí está la respuesta , usando el buen @ComponentScan va a resolver, a continuación se muestra el fragmento de código que me estoy pegando, que yo también enfrentan el mismo problema y resuelto. A continuación se resuelve y obras para el problema relacionado con el bean de creación de excepción para org.springframework.de seguridad.núcleo.userdetails.UserDetailsService


    Paso1: Escribir la Seguridad de Configuración de la Aplicación de la clase

    import org.springframework.security.core.userdetails.UserDetailsService;
    @Configuration
    @EnableWebSecurity
    public class LoginSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    @Qualifier("userDetailsServiceImpl")
    UserDetailsService userDetailsService;

    Aquí @ComponentScan no es obligatorio en LoginSecurityConfig , puede definir @ComponentScan en la raíz de configuración de la clase, como el de abajo y de importación de la LoginSecurityConfig.class LoginSecurityConfig.

    @Configuration
    @EnableWebMvc
    @ComponentScan(basePackages = { "com.example" })
    @Import(value = { LoginSecurityConfig.class })
    public class LoginApplicationConfig 

    Paso 2: Ahora Autowiring la SpringBean org.springframework.de seguridad.núcleo.userdetails.UserDetailsService

    @Service("userDetailsServiceImpl")
    public class UserDetailsServiceImpl implements org.springframework.security.core.userdetails.UserDetailsService {
    @Autowired
    UserDao userDao;
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
    User user = userDao.findByUsername(username);
    if (user == null) {
    System.out.println("User not found");
    throw new UsernameNotFoundException("Username not found");
    }
    return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), true, true, true, true, getGrantedAuthorities(user));
    }
    private List<GrantedAuthority> getGrantedAuthorities(User user) {
    List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
    authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
    return authorities;
    }
    }//End of Class
  7. 1

    Pruebe a cambiar el tipo de campo:

    @Configuration
    @EnableWebMvcSecurity
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    @Qualifier("userDetailsService")
    MemberServiceImpl userDetailsService;
  8. 0

    Estoy usando la Peatonal y se topó con el mismo problema.
    Yo podría resolver este problema por cambiar el orden en mi AppInit Clase para escanear el paquete en primer lugar, a continuación, registrar el llamado Bean

    public class AppInit implements WebApplicationInitializer {
    @Override
    public void onStartup(ServletContext servletContext) throws ServletException 
    {
    //Create webapp context
    AnnotationConfigWebApplicationContext root = new AnnotationConfigWebApplicationContext();
    root.scan("my_package");
    root.register(SpringSecurityConfiguration.class);
    ...#
    }

Dejar respuesta

Please enter your comment!
Please enter your name here