3
My system authenticates the client (it’s a web service) through the BaseCertLoginModule
, a class of Jboss based on the Jaas specification. In fact my project extends this class, and this extension is called to each request to decide whether or not the user has access to the web service. I do this by taking the request serial (SSL two-way) and doing a database search with this serial.
All this (authentication) is working fine. What I wanted now is to resolve the authorization. I wanted to use the annotation @RequiredRole
, because I already define the user roles in my LoginModule
. I thought I’d just do that:
@Override
@WebMethod
@RequiredRole("MASTER")
public void cancelarLaudo(CancelamentoLaudoRequest cancelamentoLaudoRequest)...
Where cancelarLaudo
is an operation of my web service SOAP.
But it didn’t work. :)
What else would I have to do? I’ve read the Demoiselle documentation, but it wasn’t clear how I would make it work along with the Demoiselle scheme LoginModule
that I already have.
Man LoginModule
:
package br.gov.serpro.sislvws.security.loginmodule;
import java.security.Principal;
import java.security.acl.Group;
import java.security.cert.X509Certificate;
import javax.persistence.NoResultException;
import javax.security.auth.login.LoginException;
import org.jboss.logging.Logger;
import org.jboss.security.SimpleGroup;
import org.jboss.security.SimplePrincipal;
import org.jboss.security.auth.spi.BaseCertLoginModule;
import br.gov.frameworkdemoiselle.util.Beans;
import br.gov.serpro.sislv.entity.CertificadoDigital;
import br.gov.serpro.sislv.entity.Entidade;
import br.gov.serpro.sislv.persistence.EntidadeDAO;
public class SislvLoginModule extends BaseCertLoginModule {
private Logger logger = Logger.getLogger(this.getClass());
private EntidadeDAO entidadeDAO;
public SislvLoginModule() {
entidadeDAO = Beans.getReference(EntidadeDAO.class);
}
@Override
protected Principal createIdentity(String arg0) throws Exception {
X509Certificate certificate = (X509Certificate) getCredentials();
try {
Principal principal = new SislvPrincipal(certificate);
log.info("Usuário identificado: " + principal);
return principal;
} catch (Exception e) {
String message = "Falha ao tentar autenticar o certificado " + certificate.toString();
logger.error(message, e);
throw e;
}
}
@Override
protected Group[] getRoleSets() throws LoginException {
CertificadoDigital certificado = certificado();
try {
Entidade entidade = entidadeDAO.findBy(certificado);
String role = entidade.getTipoEntidade().toString();
SimpleGroup roles = new SimpleGroup("Roles");
SimplePrincipal user = new SimplePrincipal(role);
roles.addMember(user);
return new Group[] { roles };
} catch (NoResultException e) {
String msg = certificado + " não autorizado a acessar o web service.";
logger.error(msg);
throw new LoginException(msg);
} catch (Exception e) {
logger.error("Erro inesperado durante a autenticação", e);
throw new LoginException();
}
}
private CertificadoDigital certificado() throws LoginException {
SislvPrincipal identity = null;
try {
identity = (SislvPrincipal) getIdentity();
CertificadoDigital cert = new CertificadoDigital();
cert.setCommonName(identity.getCommonName());
cert.setSerial(identity.getSerial());
cert.setCommonNameEmissor(identity.getCommonNameEmissor());
return cert;
} catch (Exception e) {
logger.error("Erro inesperado durante a autenticação", e);
throw new LoginException();
}
}
}
Jboss configuration to activate the LoginModule
:
<security-domain name="SislvSecurityDomain">
<authentication>
<login-module code="br.gov.serpro.sislvws.security.loginmodule.SislvLoginModule" flag="required">
<module-option name="verifier" value="org.jboss.security.auth.certs.AnyCertVerifier" />
</login-module>
</authentication>
...