2011-02-24 9 views
5

Estoy tratando de aplicar seguridad en mi aplicación de primavera usando tablas de base de datos.seguridad de primavera con detalles de usuario personalizados

Lo que tengo hasta ahora en mi applicationContext-Security es:

<beans:bean id="userDetailsService" class="org.intan.pedigree.service.UserDetailsServiceImpl"></beans:bean> 

<http auto-config='true'> 
    <intercept-url pattern="/**" access="ROLE_USER" /> 
</http> 

<beans:bean id="daoAuthenticationProvider" 
    class="org.springframework.security.authentication.dao.DaoAuthenticationProvider"> 
    <beans:property name="userDetailsService" ref="userDetailsService" /> 
</beans:bean> 

<beans:bean id="authenticationManager" 
    class="org.springframework.security.authentication.ProviderManager"> 
    <beans:property name="providers"> 
     <beans:list> 
      <beans:ref local="daoAuthenticationProvider" /> 
     </beans:list> 
    </beans:property> 
</beans:bean> 


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

mi implementación de userDetailsService se ve de la siguiente manera:

package org.intan.pedigree.service; 

import org.intan.pedigree.dao.UserEntityDAO; 
import org.intan.pedigree.dao.UserEntityDAOImpl; 
import org.intan.pedigree.form.UserEntity; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.dao.DataAccessException; 
import org.springframework.stereotype.Service; 
import org.springframework.transaction.annotation.Transactional; 
import org.springframework.security.core.userdetails.UserDetails; 
import org.springframework.security.core.userdetails.UserDetailsService; 
import org.springframework.security.core.userdetails.UsernameNotFoundException; 

@Service("userDetailsService") 
public class UserDetailsServiceImpl implements UserDetailsService { 

    @Autowired 
    private UserEntityDAO dao; 
    @Autowired 
    private Assembler assembler; 

    @Transactional(readOnly = true) 
    public UserDetails loadUserByUsername(String username) 
      throws UsernameNotFoundException, DataAccessException { 

     UserDetails userDetails = null; 
     UserEntity userEntity = dao.findByName(username); 
     if (userEntity == null) 
       throw new UsernameNotFoundException("user not found"); 

     return assembler.buildUserFromUserEntity(userEntity); 
    } 
} 

mi ensamblador se ve de la siguiente manera:

package org.intan.pedigree.service; 

import java.util.ArrayList; 
import java.util.Collection; 

import org.intan.pedigree.form.SecurityRoleEntity; 
import org.intan.pedigree.form.UserEntity; 
//import org.springframework.security.core.GrantedAuthority; 
//import org.springframework.security.core.authority.GrantedAuthorityImpl; 
//import org.springframework.security.core.userdetails.User; 
import org.springframework.security.core.GrantedAuthority; 
import org.springframework.security.core.authority.GrantedAuthorityImpl; 
import org.springframework.security.core.userdetails.User; 
import org.springframework.stereotype.Service; 
import org.springframework.transaction.annotation.Transactional; 

@Service("assembler") 
public class Assembler { 

    @Transactional(readOnly = true) 
    User buildUserFromUserEntity(UserEntity userEntity) { 

    String username = userEntity.getUsername(); 
    String password = userEntity.getPassword(); 
    boolean enabled = userEntity.isActive(); 
    boolean accountNonExpired = userEntity.isActive(); 
    boolean credentialsNonExpired = userEntity.isActive(); 
    boolean accountNonLocked = userEntity.isActive(); 
    Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>(); 
    for (SecurityRoleEntity role : userEntity.getUserSecurityRoleEntity()) { 
     authorities.add(new GrantedAuthorityImpl(role.getName())); 
    } 

    User user = new User(username, password, enabled, 
     accountNonExpired, credentialsNonExpired, accountNonLocked, authorities); 
    return user; 
    } 
} 

ahora la entidad de usuario es:

package org.intan.pedigree.form; 

import java.util.Date; 
import java.util.HashSet; 
import java.util.Set; 

import javax.persistence.CascadeType; 
import javax.persistence.Column; 
import javax.persistence.Entity; 
import javax.persistence.GeneratedValue; 
import javax.persistence.Id; 
import javax.persistence.JoinColumn; 
import javax.persistence.JoinTable; 
import javax.persistence.OneToMany; 
import javax.persistence.Table; 
import javax.validation.constraints.NotNull; 
@Entity 
@Table(name="user") 
public class UserEntity { 

    @Id 
    @GeneratedValue 
    @Column(name="ID") 
    private int id; 
    @Column(name="first_name") 
    private String first_name; 
    @Column(name="family_name") 
    private String last_name; 
    @Column(name="dob") 
    private Date dob; 
    @Column(name="password") 
    private String password; 
    @Column(name="username") 
    private String username; 
    @Column(name="active") 
     @NotNull 
    private boolean isActive; 
    @Column(name="user_types_id") 
    private int user_types_id; 
    @Column(name="confirm_password") 
    public String confirmPassword; 
    @OneToMany(cascade = CascadeType.ALL) 
    @JoinTable(name = "user_address", joinColumns = { @JoinColumn(name = "user_id") }, 
      inverseJoinColumns = { @JoinColumn(name = "address_id") }) 
    private Set<Address> userAddress = new HashSet<Address>(0); 
    /*******************************************************************************/ 
    @OneToMany(cascade = CascadeType.ALL) 
    @JoinTable(name = "user_security_role", joinColumns = { @JoinColumn(name = "user_id") }, 
      inverseJoinColumns = { @JoinColumn(name = "security_role_id") }) 
    private Set<SecurityRoleEntity> userSecurityRoleEntity = new HashSet<SecurityRoleEntity>(0); 

    public Set<Address> getUserAddress(){ 
     return this.userAddress; 
    } 

    public void setUserAddress(Set<Address> userAddress) { 
     this.userAddress = userAddress; 
    } 
    /*****************************************************************************/ 

    public Set<SecurityRoleEntity> getUserSecurityRoleEntity(){ 
     return this.userSecurityRoleEntity; 
    } 

    public void setUserSecurityRoleEntity(Set<SecurityRoleEntity> userSecurityRoleEntity) { 
     this.userSecurityRoleEntity = userSecurityRoleEntity; 
    } 


    public boolean isActive() { 
     return isActive; 
    } 

    public void setActive(boolean isActive) { 
     this.isActive = isActive; 
    } 

    public String getConfirmPassword() { 
     return confirmPassword; 
    } 
    public void setConfirmPassword(String confirmPassword) { 
     this.confirmPassword = confirmPassword; 
    } 
    public int getId() { 
     return id; 
    } 
    public void setId(int id) { 
     this.id = id; 
    } 
    public String getFirst_name() { 
     return first_name; 
    } 
    public void setFirst_name(String first_name) { 
     this.first_name = first_name; 
    } 
    public String getLast_name() { 
     return last_name; 
    } 
    public void setLast_name(String last_name) { 
     this.last_name = last_name; 
    } 
    public Date getDob() { 
     return dob; 
    } 
    public void setDob(Date dob) { 
     this.dob = dob; 
    } 
    public String getPassword() { 
     return password; 
    } 
    public void setPassword(String password) { 
     this.password = password; 
    } 
    public String getUsername() { 
     return username; 
    } 
    public void setUsername(String username) { 
     this.username = username; 
    } 
    public int getUser_types_id() { 
     return user_types_id; 
    } 
    public void setUser_types_id(int user_types_id) { 
     this.user_types_id = user_types_id; 
    } 


} 

mi interfaz userentitydao es:

package org.intan.pedigree.dao; 

import java.util.List; 

import org.intan.pedigree.form.UserEntity; 


public interface UserEntityDAO { 
    public void removeUserEntity(Integer id); 
    public List<UserEntity> listUserEntity() ; 
    public void addUserEntity(UserEntity user) ; 
    public void updateUserEntity(UserEntity user) ; 
    public UserEntity getUserEntityByID(Integer id); 
    public UserEntity findByName(String username); 
} 

y la aplicación es:

@Repository 
public class UserEntityDAOImpl implements UserEntityDAO{ 

    @Autowired 
    private SessionFactory sessionFactory; 

    public void addUserEntity(UserEntity user) { 
     try { 
     sessionFactory.getCurrentSession().save(user); 
     } catch (Exception e) { 
      System.out.println(e); 
     } 
    } 

    public UserEntity findByName(String username) { 
     UserEntity user = (UserEntity) sessionFactory.getCurrentSession().createQuery(
       "select u form user u where u.username = '" + username + "'"); 
     return user; 

    } 

    public UserEntity getUserEntityByID(Integer id) { 
     UserEntity user = (UserEntity) sessionFactory.getCurrentSession().createQuery(
       "select u form user u where id = '" + id + "'"); 
     return user; 
    } 
    public void updateUserEntity(UserEntity user) { 
     try { 
     sessionFactory.getCurrentSession().update(user); 
     } catch (Exception e) { 
      System.out.println(e); 
     } 
    } 

    public List<UserEntity> listUserEntity() { 

     return sessionFactory.getCurrentSession().createQuery("from User") 
       .list(); 
    } 

    public void removeUserEntity(Integer id) { 
     UserEntity user = (UserEntity) sessionFactory.getCurrentSession().load(
       UserEntity.class, id); 
     if (null != user) { 
      sessionFactory.getCurrentSession().delete(user); 
     } 

    } 
} 

ahora cuando intento de implementar en Tomcat me sale la siguiente excepción:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userDetailsService': Injection of autowired dependencies failed; nested exception 
is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.intan.pedigree.dao.UserEntityDAO org.intan.pedigree.service.UserDetailsS 
erviceImpl.dao; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [org.intan.pedigree.dao.UserEntityDAO] found 
for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotatio 
n.Autowired(required=true)} 

y no importa lo que haga, no puedo entender qué está mal con eso. Cualquier consejo sería bienvenido.

muchas gracias

Respuesta

1

No veo ninguna declaración para los beans UserEntityDAOImpl o Assembler en su contexto, y no hay escaneo de componentes para autodetectar.

O bien tiene que declararlos junto con el UserDetailsServiceImpl, o agregar un <context:component-scan> en algún lugar.

+0

dentro de mi pedigree-servlet.xml yo uso: no es esto suficiente esto debe escanear todo .. mis controladores con @Controller pueden utilizar los servicios y de Dao sin problema .. :(- user529065 – giannisapi

+0

@ user529065: Spring Security no utiliza los contextos '-servlet.xml'.Necesita agregar el escaneo de componentes al contexto de la raíz de la aplicación, es decir, en el mismo contexto en el que se encuentra el material de Spring Security. – skaffman

+0

bien, agregué el escaneo de componentes y funciona ahora. pero ¿puedo hacer otra pregunta, por favor? cuando intento iniciar sesión obtengo este error de hibernación que me parece extraño: org.hibernate.hql.ast.QuerySyntaxException: token inesperado: formulario cerca de la línea 1, columna 10 [seleccione u nombre de usuario u donde u.nombre de usuario = 'giannisapi '] alguna pista sobre esto? – giannisapi

0

creo que se olvidó de definir UserEntityDAO en su contexto de aplicación.

+0

dentro de mi pedigrí-servlet.xml que utilizo: ¿Esto no es suficiente? Esto debería escanear todo ... mis controladores con @Controller pueden usar servicios y dao sin problemas ... :( – giannisapi

1

Todas las dependencias de la primavera de Seguridad (como el DAO) deben decalred en el contexto de aplicación Web raíz (applicationContext.xml u otros archivos XML configurados en <context-param> llamado contextConfigLocation), no en Conext de serlvlet (...-servlet.xml), porque los granos de Núcleo elástico de seguridad se declaran en el contexto raíz, y los beans en ese contexto no tienen acceso a los beans en el contexto del servlet.

Si usa <context:component-scan>, puede seguir this solution. Consulte también:

Cuestiones relacionadas