Caros:
Estou com um problema no JAAS e estou compartilhando com vc.
O negócio é que estou fazendo um LoginModule que esta autenticando no servidor AD via EJB3 e gerá um Principal com o User e as sua Roles, até aqui esta tudo certo .
No entanto quando estou na minha aplicação Web (com JSF) e chamo um método que verifica se um usuário pertence a uma Role ( context.getExternalContext().isUserInRole(“logado”) , SEMPRE recebo como FALSE. O mais estranho é que se executo “context.getExternalContext().getUserPrincipal();” eu recebo o usuário.
fiz um debug via console no JBoss e aparentemente ele esta criando o user e suas respectivas roles e adicionando no Principal:
11:13:27,586 INFO [STDOUT] .....inicializando
11:13:27,602 INFO [STDOUT] ..........fazendo o login
11:13:27,602 INFO [STDOUT] ..........buscando o user name e senha
11:13:27,602 INFO [STDOUT] ..............quem esta logado : teste
11:13:27,602 INFO [STDOUT] ..............senha codificada do usuario logado : [C@86f716
11:13:27,602 INFO [STDOUT] ..............senha descodificada do usuario logado : teste
11:13:27,602 INFO [STDOUT] ..........fim da busca
11:13:27,602 INFO [STDOUT] ..........validando o usuario
11:13:27,602 INFO [STDOUT] ..........validou o usuario e atribuiu as roles
11:13:27,602 INFO [STDOUT] .............dados do usuario logado
11:13:27,602 INFO [STDOUT] ..............>>> teste
11:13:27,602 INFO [STDOUT] ..............>>> [br.sanepar.security.principals.Role@1c39aa6, br.sanepar.security.principals.Role@c24ae7]
11:13:27,602 INFO [STDOUT] .............>>>Role : ADM
11:13:27,602 INFO [STDOUT] .............>>>Role : logado
11:13:27,602 INFO [STDOUT] ..........executando o commit()
11:13:27,602 INFO [STDOUT] ..............adiciona o usuario no principals br.sanepar.security.principals.User@1f7a434
11:13:27,617 INFO [STDOUT] ..............adiciona as roles no principals br.sanepar.security.principals.Role@1c39aa6
11:13:27,617 INFO [STDOUT] ..............adiciona as roles no principals br.sanepar.security.principals.Role@c24ae7
11:13:27,867 INFO [DefaultLifecycleProviderFactory] Using LifecycleProvider org.apache.myfaces.config.annotation.TomcatAnnotationLifecyclePro
11:13:27,883 INFO [TomcatAnnotationLifecycleProvider] Creating instance of demo.spring.action.ManagerBean
11:14:01,088 INFO [TomcatAnnotationLifecycleProvider] Creating instance of demo.spring.action.ManagerBean
11:14:01,104 INFO [STDOUT] nome : teste
11:14:01,104 INFO [STDOUT] faz parte da role 'logado'? : false
O meu LoginModuleSanepar.java
public class LoginModuleSanepar implements LoginModule {
protected Subject subject;
protected CallbackHandler callbackHandler;
protected Map sharedState;
private boolean commitSucceeded = false;
private boolean succeeded = false;
private Set roles = new HashSet();
private User user;
public boolean abort() throws LoginException {
// TODO Stub de método gerado automaticamente
if (!succeeded) {
return false;
} else if (succeeded && !commitSucceeded) {
succeeded = false;
} else {
succeeded = false;
logout();
}
this.subject = null;
this.callbackHandler = null;
this.sharedState = null;
this.roles = new HashSet();
System.out.println("..........executando o abort()");
return succeeded;
}
public boolean commit() throws LoginException {
// TODO Stub de método gerado automaticamente
System.out.println("..........executando o commit()");
// adiciona o usuario no principals
if (user != null && !subject.getPrincipals().contains(user)) {
System.out.println("..............adiciona o usuario no principals " + user);
subject.getPrincipals().add(user);
}
// adiciona as roles no principals
if (roles != null) {
Iterator it = roles.iterator();
while (it.hasNext()) {
Role role = (Role) it.next();
if (!subject.getPrincipals().contains(role)) {
System.out.println("..............adiciona as roles no principals " + role);
subject.getPrincipals().add(role);
}
}
}
commitSucceeded = true;
return true;
}
public void initialize(Subject subject, CallbackHandler callbackHandler,
Map sharedState, Map options) {
// TODO Stub de método gerado automaticamente
this.subject = subject;
this.callbackHandler = callbackHandler;
this.sharedState = sharedState;
System.out.println(".....inicializando");
}
public boolean login() throws LoginException {
// TODO Stub de método gerado automaticamente
System.out.println("..........fazendo o login");
getUsernamePassword();
validaUsuario();
sharedState.put("javax.security.auth.principal", user);
sharedState.put("javax.security.auth.roles", roles);
System.out.println(".............dados do usuario logado");
System.out.println("..............>>> " + user.getName());
System.out.println("..............>>> " + user.getRoles());
Collection<Role> teste = new ArrayList();
teste.addAll(user.getRoles());
for (Role r : teste)
System.out.println(".............>>>Role : "+r.getName());
return true;
}
public boolean logout() throws LoginException {
// remove o usuario e as roles do principals
subject.getPrincipals().removeAll(roles);
subject.getPrincipals().remove(user);
return true;
}
/**
* Valida login e senha no banco
*/
private void validaUsuario() throws LoginException {
System.out.println("..........validando o usuario");
if (senhaInformado.equals("teste")) {
user = new User("teste");
roles.add(new Role("logado"));
roles.add(new Role("ADM"));
user.setRoles(roles);
System.out.println("..........validou o usuario e atribuiu as roles");
return;
} else {
System.out.println("..........senha invalida");
throw new LoginException("Senha Inválida.");
}
}
/**
* Login do usuário.
*/
protected String loginInformado;
/**
* Senha do usuário.
*/
protected String senhaInformado;
/**
* Obtem o login e senha digitados
*/
protected void getUsernamePassword() throws LoginException {
System.out.println("..........buscando o user name e senha");
if (callbackHandler == null)
throw new LoginException(
"Error: no CallbackHandler available to garner authentication information from the user");
Callback[] callbacks = new Callback[2];
callbacks[0] = new NameCallback("Login");
callbacks[1] = new PasswordCallback("Senha", false);
try {
callbackHandler.handle(callbacks);
loginInformado = ((NameCallback) callbacks[0]).getName();
System.out.println("..............quem esta logado : " + loginInformado);
char[] tmpPassword = ((PasswordCallback) callbacks[1])
.getPassword();
senhaInformado = new String(tmpPassword);
((PasswordCallback) callbacks[1]).clearPassword();
System.out.println("..............senha codificada do usuario logado : " + tmpPassword.toString());
System.out.println("..............senha descodificada do usuario logado : " + senhaInformado);
} catch (java.io.IOException ioe) {
throw new LoginException(ioe.toString());
} catch (UnsupportedCallbackException uce) {
throw new LoginException(
"Error: "
+ uce.getCallback().toString()
+ " not available to garner authentication information from the user");
}
System.out.println("..........fim da busca");
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public boolean isCommitSucceeded() {
return commitSucceeded;
}
public void setCommitSucceeded(boolean commitSucceeded) {
this.commitSucceeded = commitSucceeded;
}
public boolean isSucceeded() {
return succeeded;
}
public void setSucceeded(boolean succeeded) {
this.succeeded = succeeded;
}
}
meu web.xml
<login-config>
<auth-method>FORM</auth-method>
<realm-name>LoginModuleSanepar</realm-name>
<form-login-config>
<form-login-page>/security/login.faces</form-login-page>
<form-error-page>/security/error_login.faces</form-error-page>
</form-login-config>
</login-config>
<security-constraint>
<display-name>aplicacao</display-name>
<web-resource-collection>
<web-resource-name>aplicacao</web-resource-name>
<url-pattern>/pages/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>logado</role-name>
</auth-constraint>
</security-constraint>
<!-- Lista de Roles -->
<security-role>
<role-name>logado</role-name>
</security-role>
Aqui ocorre outro problema, por exemplo se eu seto a tag - auth-constraint - para a role-name = logado. Ele até autentica, mas apresenta um erro : HTTP Status 403 - Access to the requested resource has been denied para testa eu coloquei um ‘*’ no role-name do auth-constraint e autenticou. Mas como podemos ver, sem a Role.
e como estou utilizando o JBOSS, tenho um jboss-web.xml que esta assim…
<?xml version="1.0" encoding="UTF-8"?>
<jboss-web>
<security-domain>java:/jaas/LoginModuleSanepar</security-domain>
</jboss-web>
Eu não sei o que esta havendo, mas desconfio que o problema esteja diretamente dentro do LoginModule. Mas não entendo porque ele autentica e faz tudo certinho.
Se puderem me ajudar, ficarei grato.
Desde já obrigado