My system authenticates the client (it's a web service) through BaseCertLoginModule
, a JBoss class based on the JaaS specification. In fact my project extends this class, and this extension is called upon every request to decide whether the user has access to the web service or not. I do this by getting the two-way SSL (SSL two-way) serial and searching the database with this serial.
This all (authentication) is working legal. What I wanted now is resolve the authorization. I wanted to use the @RequiredRole
annotation because I already set user roles in my LoginModule
. I thought I would just do this:
@Override
@WebMethod
@RequiredRole("MASTER")
public void cancelarLaudo(CancelamentoLaudoRequest cancelamentoLaudoRequest)...
Where cancelarLaudo
is an operation of my SOAP web service.
But it did not work. :)
What else would I have to do? I've read Demoiselle documentation, but it was not clear how I would work with the LoginModule
scheme I already have.
My 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();
}
}
}
Configuring JBoss to enable 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>
...