Spring não reconhece EJB Stateless para injeção de dependência

8 respostas
spring
raphaeloneves

Saudações, meu caros.

Estou implementando uma solução de autenticação e autorização baseada no Spring Security num projeto feito com JEE.
Meu problema é o seguinte: Na classe AppUserDetailsService tenho uma injeção de dependência do meu repository, que é um EJB Stateless, porém, o spring não consegue fazer essa injeção e lança um NPE.

Classe AppUserDetailsService que é um bean do Spring

@Service
public class AppUserDetailsService implements UserDetailsService {

    @Inject
    Usuarios usuarios;

    @Override
    public UserDetails loadUserByUsername(String nome) throws UsernameNotFoundException {
        Usuario usuario = usuarios.findByUsername(nome);
        UsuarioSistema user = null;
        if (usuario != null) {
            user = new UsuarioSistema(usuario, getGrupos(usuario));
        }
        return user;
    }

    private Collection<? extends GrantedAuthority> getGrupos(Usuario usuario) {
        List<SimpleGrantedAuthority> authorities = new ArrayList<>();

        for (Grupo grupo : usuario.getGrupos()) {
            authorities.add(new SimpleGrantedAuthority(grupo.getNome().toUpperCase()));
        }

        return authorities;
    }

}

Meu EJB Stateless que representa meu Repositório de usuários

@Stateless
public class Usuarios{

    @PersistenceContext
    private EntityManager manager;

    private Usuarios usuarios;

    @Override
    public Usuario findByUsername(String username) {
        return manager.createQuery("from Usuario where nome = :nome", Usuario.class)
                .setParameter("nome", username).getSingleResult();
    }

}

A NPE é lançada na injeção do EJB dentro do Bean Spring.

Também tentei a abordagem de criar uma interface Usuarios e criar sua devida implementação como EJB. Feito isso, registrei o EJB criado por meio do JNDI no applicationContext do Spring, ficando da seguinte forma:

Bean Spring

@Service
public class AppUserDetailsService implements UserDetailsService {

    @Autowired
    Usuarios usuarios;
........
}

applicationContext.xml

<jee:local-slsb jndi-name="java:global/projeto-base/UsuariosImpl!br.com.raphaelneves.dao.Usuarios"
                    id="usuarios" business-interface="br.com.raphaelneves.dao.Usuarios" />

    <beans:bean id="usuariosImpl" class="br.com.raphaelneves.dao.UsuariosImpl">
        <beans:property name="usuarios" ref="usuarios" />
    </beans:bean>

Alguém poderia dar uma luz de como fazer o Spring reconhecer e injetar o EJB Stateless na implementação da UserDetailsService? :frowning:

8 Respostas

M

Bom dia, @raphaeloneves.

Eu estou enfrentando o mesmo problema que você descreveu.
Você encontrou alguma solução?

Obrigado

igor_ks

Sao contextos diferentes… Spring vai entender anotacoes/contextos Spring, e o mesmo pra EJBs

L

Em todos estes anos nessa indústria vital, eu nunca vi algo assim.
A ideia do EJB é justamente não precisar de coisas externas, como o Spring.
Até onde sei, um EJB só pode ser injetado em outro EJB, numa servlet ou num managed bean.
EJB tem como filosofia depender de implementação e ambiente de execução (application servers).
O Spring, por sua vez, foi desenvolvido para ser livre, independente de implementação ou ambiente de execução. Ele gerencia de uma forma específica seus beans, seria outra thread, para simplificar.

M

Valeu pela atenção.

Mas apenas para tentar deixar a discussão mais clara: a idéia é utilizar o Spring Security como framework de segurança em uma aplicação Java EE (JSF, JPA, EJB = @Stateless e @PersistenceContext para instanciar uma entity manager).

Obrigado

L

E por quê não JAAS?

M

Vou procurar um tópico que compare o JAAS e o Spring Security (ou Apache Shiro) para responder sua pergunta.

Valeu

raphaeloneves

Marcel, este link me ajudou.
Na documentação do Spring Security tem uma seção que fala dessa injeção tb. Caiu como uma luva pra mim.
A abordagem não é a mais bonita, mas resolveu.

No meu caso foi por familiaridade e falta de tempo pessoal e de projeto pra encarar uma curva de aprendizado mais extensa e complexa - no meu ponto de vista - que é a do JAAS. Além disso, tive dificuldade de encontrar material de referência do tipo “how to” e “from scratch”. Talvez o tempo de entrega fez com que eu entrasse no comodismo de entregar o que tinha mais facilidade e conhecimento.

Ainda neste viés, conhecem algum material de “fácil entendimento” que possibilite implementar o JAAS com roles dinâmicas?

M

@raphaeloneves, obrigado pela atenção.

Percebi que meu problema é diferente do problema que você enfrentou. Eu gostaria de utilizar Spring Security sem precisar do core Spring. O seu objeto é um bean do Spring e o meu não é.

A minha classe

@Named
public class UsuarioService implements UserDetailsService {

	@Inject
	UsuarioDAO usuarioDAO;
	
	@Override
	public UsuarioSpring loadUserByUsername(final String login) throws UsernameNotFoundException {
		return usuarioDAO.retornaUsuarioPeloLogin(login); 
	}	
}

O erro ocorre na injeção do UsuarioDAO que é um bean @Stateless e tem a injeção do Entity Manager através da notação @PersistenceContext.

Valeu

Criado 12 de dezembro de 2016
Ultima resposta 17 de abr. de 2017
Respostas 8
Participantes 4