@Requiredrole with Basecertloginmodule

Asked

Viewed 119 times

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>
                ...

1 answer

1

Opa, the main thing that was missing was to activate the Interceptor RequiredRoleInterceptor in the beans.xml. Besides, I extended the class ServletAuthorizer Demoiselle to implement the method hasRole. And, finally, this class was registered in Demoiselle.properties.

Now the solution is working, but still wanted to improve one aspect.

This is my authorization class:

    package br.gov.serpro.sislvws.ws.autorizacao;

    import javax.enterprise.context.RequestScoped;
    import javax.inject.Inject;

    import br.gov.frameworkdemoiselle.security.ServletAuthorizer;
    import br.gov.serpro.sislvws.security.loginmodule.RequestAutenticado;

    @RequestScoped
    public class RoleBasedAuthorizer extends ServletAuthorizer {

        private static final long serialVersionUID = 1L;

        @Inject
        private RequestAutenticado requestAutenticado;

        @Override
        public boolean hasRole(String role) throws Exception {
            String tipoEntidade = requestAutenticado.getEntidadeCliente().getTipoEntidade().toString();
            return tipoEntidade.equals(role);
        }

    }

In this solution, there is a repetition of the logic to define the role of the logged in "user". This logic appears getRoleSets of the login module and hasRole of the authorizer. What I would think is better is if the role setting was only the login module, and if in the authorizer I was able to rescue which scroll was already set there in login module.

I tried searches like "(jboss|jaas) Retrieve role defines on login module", but I still can’t resolve.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.