= CDI Realm
:index-group: Security
:jbake-type: page
:jbake-status: published

Este exemplo mostra como proteger o acesso a um web resource fornecido por um servlet. Para isso, 
usaremos realms.

Um https://javaee.github.io/tutorial/security-intro005.html#BNBXJ[realm], no ecossistema JavaEE, é 
um domínio de politica de segurança definido para um web server ou um application server. Um realm 
contém uma coleção de usuários, que podem ou não ser atribuídos a um grupo.

Um realm, basicamente, especifica uma lista de usuários e funções. É um "banco de dados" de usuários 
com senhas associadas e possíveis papeis. A especificação de servlet não especifica uma API para 
definir uma lista de usuários e funções para um determinado aplicativo. Por essa razão, o Tomcat 
servlet container define uma interface, `org.apache.catalina.Realm`. Mais informações podem ser 
encontradas https://tomcat.apache.org/tomcat-9.0-doc/realm-howto.html[aqui].

No servidor de aplicação TomEE, o mecanismo usado pelo Tomcat para definir um realm para um servlet 
é reutilizado e aprimorado. Mais informações podem ser encontradas https://www.tomitribe.com/blog/tomee-security-episode-1-apache-tomcat-and-apache-tomee-security-under-the-covers[aqui].

== Exemplo

Este exemplo mostra um secured servlet (servlet seguro/protegido) usando um realm. O secured servlet 
tem uma funcionalidade simples, apenas ilustrar os conceitos aqui explicados:

....
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/servlet")
public class SecuredServlet extends HttpServlet {
    @Override
    protected void service(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write("Servlet!");
    }
}
....

Para proteger este servlet, adicionaremos a seguinte classe:

....
import javax.enterprise.context.RequestScoped;
import java.security.Principal;

@RequestScoped // just to show we can be bound to the request but @ApplicationScoped is what makes sense
public class AuthBean {
    public Principal authenticate(final String username, String password) {
        if (("userA".equals(username) || "userB".equals(username)) && "test".equals(password)) {
            return new Principal() {
                @Override
                public String getName() {
                    return username;
                }

                @Override
                public String toString() {
                    return username;
                }
            };
        }
        return null;
    }

    public boolean hasRole(final Principal principal, final String role) {
        return principal != null && (
                principal.getName().equals("userA") && (role.equals("admin")
                        || role.equals("user"))
                        || principal.getName().equals("userB") && (role.equals("user"))
        );
    }
}
....

A classe define dois métodos: `authenticate` e `hasRole`.
Ambos métodos vão ser utilizados pela classe `LazyRealm`, implementada no servidor de aplicação TomEE.
Este realm é configurado no arquivo `webapp/META-INF/context.xml`:

....
<Context preemptiveAuthentication="true">
  <Valve className="org.apache.catalina.authenticator.BasicAuthenticator" />
  <Realm className="org.apache.tomee.catalina.realm.LazyRealm"
         cdi="true" realmClass="org.superbiz.AuthBean"/>
</Context>
....

A classe `AuthBean` define um "banco de dados" com dois usuários: userA (papel de admin) e 
userB (papel de usuário), ambos possuem a senha test.
A classe `org.apache.tomee.catalina.realm.LazyRealm` vai carregar nossa classe `AuthBean` e vai usa-la 
para verificar se um usuário tem acesso ao conteúdo fornecido pelo nosso servlet.

== Testes

....
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.AuthCache;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.impl.client.BasicAuthCache;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.apache.openejb.arquillian.common.IO;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.arquillian.test.api.ArquillianResource;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.EmptyAsset;
import org.jboss.shrinkwrap.api.asset.FileAsset;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.io.File;
import java.io.IOException;
import java.net.URL;

import static org.hamcrest.CoreMatchers.startsWith;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;

@RunWith(Arquillian.class)
public class AuthBeanTest {
    @Deployment(testable = false)
    public static WebArchive createDeployment() {
        return ShrinkWrap.create(WebArchive.class, "low-typed-realm.war")
                .addClasses(SecuredServlet.class, AuthBean.class)
                .addAsManifestResource(new FileAsset(new File("src/main/webapp/META-INF/context.xml")), "context.xml")
                .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml");
    }

    @ArquillianResource
    private URL webapp;

    @Test
    public void success() throws IOException {
        assertEquals("200 Servlet!", get("userA", "test"));
    }

    @Test
    public void failure() throws IOException {
        assertThat(get("userA", "oops, wrong password"), startsWith("401"));
    }

    private String get(final String user, final String password) {
        final BasicCredentialsProvider basicCredentialsProvider = new BasicCredentialsProvider();
        basicCredentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(user, password));
        final CloseableHttpClient client = HttpClients.custom()
                .setDefaultCredentialsProvider(basicCredentialsProvider).build();

        final HttpHost httpHost = new HttpHost(webapp.getHost(), webapp.getPort(), webapp.getProtocol());
        final AuthCache authCache = new BasicAuthCache();
        final BasicScheme basicAuth = new BasicScheme();
        authCache.put(httpHost, basicAuth);
        final HttpClientContext context = HttpClientContext.create();
        context.setAuthCache(authCache);

        final HttpGet get = new HttpGet(webapp.toExternalForm() + "servlet");
        CloseableHttpResponse response = null;
        try {
            response = client.execute(httpHost, get, context);
            return response.getStatusLine().getStatusCode() + " " + EntityUtils.toString(response.getEntity());
        } catch (final IOException e) {
            throw new IllegalStateException(e);
        } finally {
            try {
                IO.close(response);
            } catch (final IOException e) {
                // no-op
            }
        }
    }
}
....

O teste usa o Arquillian para iniciar o servidor de aplicação e carregar o servlet.
Existem dois métodos de teste: `success`, onde nosso servlet é acessado com o usuário e senha corretos,
e `failure`, onde nosso servlet é acessado com uma senha incorreta.

O exemplo completo pode ser encontrado https://github.com/apache/tomee/tree/master/examples/cdi-realm[aqui].
É um projeto Maven, e o teste pode ser executado com o comando `mvn clean install`.
