Cara, bom dia!
- Respondendo seu primeiro post, com relação ao spring security. Para customizar o serviço de obtenção de dados do usuário a titulo de efetivação de login, de modo a você fazer usando um Web Service, um xml, acessando uma fachada de um outro subsistema, enfim… fazendo o que vc quiser da forma como quiser, você precisa implementar um UserDetailsService. Esta interface define um método chamado loadUserByUsername e que recebe um parametro “String username” e retorna um UserDetails. O spring vai chamar esse cara passando o username do cara que ta tentando logar então sua implementação do método loadUserByUsername é que vai obter e devolver o UserDetails, que é uma interface que prover os métodos de obtenção do password, username, permissoes, etc… Então o que você tem que fazer é implementar seu UserDetailsService e no método loadUserByUsername chamar o cliente do seu webService para obter as informações do usuário e dessa forma montar um UserDetails com os dados do cara. Uma vez que o spring tem o username e a senha que o cara informou na tela de login e obteve os dados reais do usuário com o username passado, então ele vai validar a autenticação. Só que você tem que declarar no seu applicationContext.xml a implementação de UserDetailsService que vai usar. Abaixo vai um exemplo:
Exemplo de como poderia ser seu UserDetailsService acessando o WS. É só um exemplo, você deve implementar a lógica correta e real.
public class MyUserDetailsService implements UserDetailsService{
private ClienteWS clienteWS;
public MyUserDetailsService() {
clienteWS = new ClienteWS();
}
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException {
UserDetailsImpl user = clienteWS.findUser(username);
if (user == null)
throw new UsernameNotFoundException("Usuário não encontrado");
return user;
}
}
Implementar exemplo de UserDetails.
public class UserDetailsImpl implements UserDetails{
private static final long serialVersionUID = 1L;
private String username;
private String password;
private Collection<GrantedAuthority> authorities;
public UserDetailsImpl(String username, String password,
Collection<GrantedAuthority> authorities) {
this.username = username;
this.password = password;
this.authorities = authorities;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return authorities;
}
@Override
public String getPassword() {
return password;
}
@Override
public String getUsername() {
return username;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
@Override
public int hashCode() {
return getUsername().hashCode();
}
@Override
public boolean equals(Object obj) {
if (obj instanceof UserDetailsImpl) {
return getUsername().equals(((UserDetailsImpl) obj).getUsername());
}
return false;
}
}
Os métodos equals e hashcode são importantes para o sprign security fazer comparações entre os usuários logados, como por exemplo, quando vc define que um usuário só pode ter no máximo uma sessão ativa, então se um usuário tiver logado e este mesmo usuário vai fazer login em outro browser ou outra máquina por exemplo, o spring security usa esses métodos para verificar e comparar se o usuário ja esta logado e assim efetuar o devido tratamente.
Agora você precisa declarar no seu applicationContext.xml que vai usar sua implementação de UserDetailsService. Como abaixo:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
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.1.xsd">
<!-- Aqui ficam suas demais configurações de segurança, como as urls, suas devidas autorizações, etc.. -->
<bean id="myUserDetailsService" class="exemplo.MyUserDetailsService"/>
<security:authentication-manager>
<security:authentication-provider user-service-ref="myUserDetailsService"/>
</security:authentication-manager>
</beans>
Pronto, agora quando o spring vai usar a sua implementação de UserDetailsService para obter as informações de autenticação de usuários e assim efetivar/validar a autenticação dos mesmos.
-
Respondendo sua outra questão com relação ao ExceptionHandler do demoiselle, não tenho certeza mas pode ser que ele só funcione com RuntimeException. Então muda o parametro do teu metodo tratarDataException para RunTimeException e testa. Caso ainda assim não funcione, posta aqui o seu BC e me diz onde que vc ta lançando a exception para testar se o exceptionhandler ta funcionando. Pois logicamente para ele funcionar alguem tem que lançar uma exceção e jogar pra cima até a visão e nenhum try catch captura-lo. Então testa se nao fucnionar, posta ai pra agente ver o que ta acontecendo.
-
Uma outra coisa que quero te dizer é que já que vc ja anotou sua classe MB com @ViewController você não precisa anotar com @Controller pois @ViewController é um tipo de Controller e vai funcionar do mesmo jeito, é como uma especialização de controladores só que de visão. Se abrir o código de @ViewController, veja que esta annotation ja esta anotada com @Controller, então não tem necessidade de repeti-la em seu MB, vc estará sendo redundante.
Cara, vou te dizer uma coisa. Não sei por qual motivo, razão ou circunstancia você ta usando esse Demoiselle. Conheço esse framework. E posso te dizer por conhecimento de causa. Esse framework é horrível. Prover soluções mau feitas e mau projetadas de de coisas que outros frameworks de verdade e consolidados na comunidade fornecem com maestria. Use um framework de verdade, um framework solido e consolidado na comunidade. Use um framework de verdade, um framework em outras palavras que é um FRAMEWORK e não esse conjunto de classes mau escritas, mau projetadas, mau documentadas, cheio de bugs, chamado Demoiselle. Em outras palavras, USE O SPRINGFRAMEWORK.
Posso te dar todo o suporte e orientação, se tiver alguma dúvida para usar o spring no que quiser. Inclusive, para remover esse demoiselle e aplicar um verdadeiro container de inversão de controle aplicado a injeção de dependencias, como o spring, um verdadeiro gerenciador transparente (E CONFIÁVEL) de transações, spring, enfim, me diga o que quer e te digo o que usar do spring e como aplica-lo a sua arquitetura. Claro que aqui nao da pra explicar tudo. Mas te passo artigos e posts onde poderá buscar seu caminho. E o melhor de tudo, TUDO INTEGRADO, pois tudo é spring, e mesmo o que não é spring, como JSF por exemplo, ou hibernate ou jpa, integrado também com spring, que fornece integração nativa a estes frameworks de forma elegante. E mesmo onde o spring não prover, sua arquiterua flexivel, prover diversos pontos configuraveis e de estenção, que lhe permitem de forma segura e elegante prover o comportamente que deseja.
Então, é isso, springframework cara, e versão atual do framework a 3, ta bem melhor, melhor ainda. Um framework de verdade e de confiança.
É isso, espero ter ajudado.