Tuesday, December 14, 2010

SpringRoo com Segurança e Repositório Usuários em BD Relacional

Apesar do Spring Roo não contar com nenhum add-on no módulo de segurança pra configurar um repositório de usuários em Banco de Dados Relacional, isso é muito simples de resolver.

Basta informar ao Spring que ele deve usar o DaoAuthenticationProvider como provedor de autenticação no Security. No applicationContext-security.xml:

    <authentication-manager alias="authenticationManager">
       <authentication-provider ref="daoAuthenticationProvider"/>
    </authentication-manager>

Depois é só definir o bean do DaoAuthenticationProvider, vincular o bean JdbcDaoImpl como service, com o DataSource e Queries mapeadas. No applicationContext.xml:

  <bean id="daoAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
    <property name="userDetailsService" ref="jdbcUserDetailsService"/>
  </bean>

  <bean id="jdbcUserDetailsService" class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl">
    <property name="dataSource" ref="?"/>
    <property name="usersByUsernameQuery" value="?"/>
    <property name="authoritiesByUsernameQuery" value="?"/>
  </bean>

Na property dataSource informe respectivo DataSource do projeto, a query para busca de usuários em usersByUsernameQuery e a busca de perfis em authoritiesByUsernameQuery.


Veja também mais sobre Spring Roo no Globalcoders e aqui no blog.

http://twitter.com/edermag
http://www.yaw.com.br/

Monday, December 13, 2010

Aplicando Segurança no Spring Roo através do Spring Security

Como aplicar/habilitar mecanismo de segurança em aplicativo desenvolvido com Spring Roo? Ou melhor, como usar Spring Security com o Spring Roo? Esse post responde essas perguntas.

A instalação e configuração do Spring Security é a mesma de um aplicativo que já usa Spring Web MVC. MAS o pulo do gato é resolver isso através do shell do Spring Roo, com mais um comando esperto.

Comece definindo a estrutura do aplicativo no Spring Roo, depois execute o comando:

_> security setup


Altere o arquivo applicationContext-security.xml indicando o padrão de url que aciona o mecanismo de segurança segurança, por exemplo:
    <intercept-url pattern="/pastaProtegida/**" access="isAuthenticated()" /> 

Pronto! É só empacotar [perform package] e rodar a aplicação [mvn tomcat:run].


Mas... o que o Roo faz por trás das cortinas?

  • Primeiro configura a dependência do Spring Security (pom.xml);
  • Depois cria um arquivo xml com as diretrizes de segurança: applicationContext-security.xml
     <http auto-config="true" use-expressions="true">
        <form-login 
           login-processing-url="/resources/j_spring_security_check" 
           login-page="/login" 
           authentication-failure-url="/login?login_error=t"/>
        <logout logout-url="/resources/j_spring_security_logout"/>
       
        <!-- primeiro so admin, segundo qualquer autenticado, terceiro e quarto nao precisa de login -->
        <intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')"/>
        <intercept-url pattern="/restrito/**" access="isAuthenticated()" />
        <intercept-url pattern="/free/**" access="permitAll" />
        <intercept-url pattern="/**" access="permitAll" />
    </http>

    <!-- define o mecanismo de seguranca simples (estatico) com os usuarios: admin/admin e user/user -->
    <authentication-manager alias="authenticationManager">
        <authentication-provider>
            <password-encoder hash="sha-256"/>
            <user-service>
                <user name="admin" password="8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918" authorities="ROLE_ADMIN"/>
            <user name="user" password="04f8996da763b7a969b1028ee3007569eaf3a635486ddab211d512c85b9df8fb" authorities="ROLE_USER"/>
        </user-service>
        </authentication-provider>
    </authentication-manager>

  • Cria uma página com formulário de login:
Trecho de /WEB-INF/views/login.jspx
    ...
    <form action="/static/resources/j_spring_security_check" method="POST">
      <div>
        <label for="j_username">
          <spring:message code="security_login_form_name" />
        </label>
        <input id="j_username" type='text' name='j_username' />
    ...
      </div>
      <br />
      <div>
        <label for="j_password">
          <spring:message code="security_login_form_password" />
        </label>
        <input id="j_password" type='password' name='j_password' />
        ...
      </div>
      ...
    </form>
    ...

  • Configura a página de login no arquivo view.xml (usado pelo Tiles):
     <definition extends="public" name="login">
        <put-attribute name="body" value="/WEB-INF/views/login.jspx"/>
    </definition>  

  • Declara o filtro do Spring Security (springSecurityFilterChain) no web.xml:
    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>
         org.springframework.web.filter.DelegatingFilterProxy
        </filter-class>
    </filter>

  • Configura a página de login no webmvc-config.xml:
    <mvc:view-controller path="/login"/>


Veja mais sobre Spring Security.
Veja também mais sobre Spring Roo no Globalcoders e aqui no blog.

Spring Roo: Mais agilidade com qualidade!

http://twitter.com/edermag
http://www.yaw.com.br/

Monday, September 20, 2010

Configurar DataSource [Hibernate + Oracle + Tomcat 6] aplicação c/ Spring Roo

Criar e configurar um aplicativo c/ Spring Roo para usar JPA c/ Hibernate no Oracle é muito simples. Pelo terminal no "prompt" do Roo, inicialmente, são 5 comandos:
$ mkdir projetoteste
$ cd projetoteste
$ roo    //assumindo que o roo ja estava instalado
$ project --toplevelPackage br.com.yaw
$ persistence setup --provider HIBERNATE --database ORACLE --username eder --password 123

Esse último comando vai gerar um warning com a informação de que não foi possível encontrar o jar do Oracle no repositório Maven, a instalação do driver será manual.

Na realidade o Roo define a conexão com o banco de dados dentro do aplicativo, veja os arquivos META-INF/spring/database.properties e META-INF/spring/applicationContext.xml.

Simples assim! Agora seria usar outros comandos para criar as entidades, controladores e as telas, executando por exemplo no Tomcat 6. Veja a demo do Roo.

Mas como utilizar um DataSource definido no Tomcat? Nesse wiki algumas dicas de como configurar o DataSource no Tomcat.

A forma mais dificil de configurar o DataSource no projeto é ir ao arquivo META-INF/spring/applicationContext.xml e substituir  a definição do bean dataSource [BasicDataSource] por:
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
  <property name="jndiName" value="java:comp/env/jdbc/MeuOracleDS"/>
</bean>

Ou via "prompt" do Roo no comando persistence setup:
$ persistence setup --provider HIBERNATE --database ORACLE
   --username eder --password 123 --jndiDataSource jdbc/MeuOracleDS

http://twitter.com/edermag
http://www.yaw.com.br/

Tuesday, September 14, 2010

Consumir WebService com autenticação usando o wsimport

O wsimport é uma ferramenta bem simples, aquelas de linha de comando, disponibilizada no jdk. Sua função é criar a infra-estrutura necessária para "consumir" Web Services a partir do wsdl, sem muita dor de cabeça. Na realidade o wsimport gera o código baseado no JAX-WS resolvendo a burocracia para acionar o Web Service com o mínimo de esforço.

Um exemplo de como usar o wsimport:
wsimport -p br.com.yaw.ws -s src -d bin http://url.servico/xpto?wsdl

O parametro -p indica o pacote para a geração das classes java, -s o diretório dos fontes e -d conteúdo output (binário por exemplo). Por fim, o mais importante, a caminho do wsdl.

O código gerado não é complexo e depende só do jdk, sem a necessidade de outra API ou de algum container JEE. Simples assim, é só criar uma classe c/ main e com código acionando o webservice...

De forma geral o wsimport gera uma classe Service que representa o webservice no cliente, factory do Proxy que faz a comunicação c/ o EndPoint.
Um "pseudo-código" para consumir um catalogo de produtos seria:

CatalogoProdutosService service = new CatalogoProdutosService();
CatalogoProdutos proxy = service.getCatalogoProdutosPort();
List<Produtoto> produtos = proxy.getProdutos();

E se o EndPoint exige autenticação? Muito simples, o objeto Proxy (CatalogoProdutos é uma interface) também implementa BindingProvider que provê acesso ao protocolo e contexto vinculado. Através dela configuro o usuário e senha, o código ficaria:

CatalogoProdutosService service = new CatalogoProdutosService();
CatalogoProdutos proxy = service.getCatalogoProdutosPort();
//dados para o login 
((BindingProvider)proxy).getRequestContext()
     .put(BindingProvider.USERNAME_PROPERTY, "jose");
((BindingProvider)proxy).getRequestContext()
     .put(BindingProvider.PASSWORD_PROPERTY, "123");
List<Produtoto> produtos = proxy.getProdutos();

Para usar Web Service com Http(s) primeiro é necessário importar o certificado e alterar a url do wsdl.


http://twitter.com/edermag
http://www.yaw.com.br

Thursday, September 02, 2010

A participação da YaW no TDC2010

Nos dias 20, 21 e 22 de Agosto aconteceu a 4a Edição do The Developers Conference, o TDC2010, evento de desenvolvedores para desenvolvedores, organizado pela Globalcode. Nesse ano a Globalcode inovou trazendo variedade de assuntos com 13 trilhas, em parceria com outras Empresas/Grupos/Profissionais Independentes, aumentando o "menu" tornando o evento completo a um valor simbólico. E de quebra com transmissão online, favorecendo principalmente o pessoal fora de SP.

O evento foi incrível, uma mistura fantástica de assuntos e comunidades em uma vibe bem interessante com muita troca de informação e networking, além da chance de rever vários amigos, quem foi sabe o que estou falando. Pra quem não foi pode ter uma idéia do que rolou nos diversos posts resumindo o que rolou no TDC2010.

Um detalhe que tornou nossa (eu e o Rafael Nunes) participação ainda mais especial é que esse foi a nossa primeira participação como YaW. Apoiamos e participamos de várias palestras em diferentes trilhas como ouvintes e palestrantes trocando um pouco de nossa experiencia com a galera. Outro ponto foi que no TDC2010 apresentamos mais 10 demonstrações, afinal evento de desenvolvedores nada melhor que código.

Na sexta logo após a abertura do evento, apresentei a primeira palestra da Trilha de JavaEE falando sobre a evolução do JSF, melhorias e o amadurecimento da versão 2.0 com a possibilidade de adotar suítes de componentes customizadas. Fiz demonstrações com as suites PrimeFaces, RichFaces e ICEFaces todas incorporadas ao ScrumToys. Na sequência o Rafael apresentou como desenvolver com JSF no Google App Engine.


A tarde, na Trilha de Spring, apresentei palestra falando sobre opções de desenvolvimento RIA com o Spring Framework junto com o Rafael. Comentei sobre o GWT, pontos fortes e fracos, e de como ele poderia ser integrado ao Spring em mais de uma opção de arquitetura com uma demonstração usando GwtRPCController. O Rafael demonstrou como é possível integrar Adobe Flex com Spring MVC.


Depois disso, na Trilha Mobile, assisti a palestra do amigo Fernando Ribeiro contando um pouco dos desafios e as oportunidades desenvolvimento BlackBerry para o mercado Corporativo com muito bom humor e riqueza de conteúdo, característico do Fribeiro. Ainda na trilha Mobile, no fim do dia, rolou um painel com representantes das principais plataformas mobile e o ponto de vista de cada um em relação a oportunidades e inovação.

Já no sábado pela manhã, assisti algumas palestras na Trilha de NOSQL, como leigo no assunto estou naquela fase de descoberta e novidades. Valeu muito para adquirir um pouco mais de conhecimento além de pegar várias dicas e referências para estudo. Depois do almoço, na Trilha Java, apresentei uma palestra sobre JavaFX partindo de um ponto de vista divertido, aonde destrinchei um jogo de Quebra-Cabeças aonde as peças são montadas dinâmicamente a partir de uma imagem. Não poderia faltar algo mais "corporativo", demonstrei um CRUD puro com JavaFX, um outro exemplo de CRUD usando JPA reaproveitando uma estrutura em Java e por fim um exemplo de integração com serviço na Web no Google App Engine acessado via REST.


Depois assisti uma ótima palestra sobre linguagens dinâmicas na JVM, onde fui apresentado ao Quercus uma alternativa de integrar PHP com Java, apresentado pelo Jefferson Prestes. Pra fechar o dia uma passada rápida na Trilha de Ruby, e mais bate-papo com amigos que encontrei no evento.

Já no Domingo não estive presente fisicamente acompanhei o TDC2010 pelo twitter. Aliás a hash #TDC2010 foi um sucesso no twitter, ficamos até no TrendsBR, um ótimo foto on-line do evento outra oportunidade para quem não foi acompanhar o que estava rolando!

O TDC2010 foi único, gostei a definição/analogia que o Jorge Diz fez aqui. Deixou saudades!


http://www.yaw.com.br
http://twitter.com/edermag

Friday, June 18, 2010

i18n de Portlets em JSF e JSP com JSTL

Existem várias formas p/ internacionalizar labels no desenvolvimento de Portlets, no post comento sobre 2 alternativas: básico com JSP e JSTL, outra opção é JavaServer Faces.

No caso de JSP e JSTL é só usar as tags fmt:setBundle e fmt:message da taglib de formatação, da mesma forma que uma aplicação web comum (sem portlets).

E o JavaServer Faces?

O mecanismo nativo de i18n do JSF funciona para portlets, é só definir os idiomas suportados no faces-config.xml, usar a tag f:loadBundle e por fim outputText e/ou outputFormat indicando o bundle e chave da label.


Em ambas alternativas, JSF ou JSP/JSTL, existe uma limitação: o title do portlet, que normalmente é definido no descritor portlet.xml, não se encaixa nos modelos de i18n descritos.

A solução é bem simples, no caso do JSTL a alternativa que encontrei foi apelar para a própria API de Portlets. No portlet.xml mapeio como title a chave que corresponde ao título no arquivo de i18n, já no código java do portlet sobreescrevo o método getTitle (herança de GenericPortlet) pegando a informação do xml e na raça acessando o bundle indicando a chave, o código seria próximo a esse:

portlet.xml
<portlet-app ... >  
  <portlet>
      ...
    <portlet-info>
      <title>meu.portlet.titulo</title>
    </portlet-info>
  </portlet>
  ...
</portlet-app>

messages_pt_BR.properties:
...
meu.portlet.titulo=Testando i18n em Portlet c/ JSTL
...

trecho do código java do Portlet:
protected String getTitle(RenderRequest request) {
    String key = super.getTitle(request);
    try {
      ResourceBundle bundle = ResourceBundle.getBundle("messages",
          request.getLocale(),getClass().getClassLoader());
      return bundle.getString(key);
    } catch (Exception ex) {
      //log4j
      log.error("Valor ["+key+"] (i18n) p/ titulo nao encontrado", ex);
      return key;
    }
  }


A solução no JSF é mais simples! Coloque a chave javax.portlet.title com o respectivo valor dentro do arquivo de i18n do aplicativo. Mas existe um macete, no portlet.xml também é preciso indicar o arquivo i18n e os idiomas suportados. A seguir um exemplo de como isso é feito.

messages_pt_BR.properties:
...
javax.portlet.title=Testando i18n em Portlet c/ JSF
...

portlet.xml
<portlet-app ... >  
  <portlet>
    ...
    <supported-locale>pt_BR</supported-locale>
    <supported-locale>en_US</supported-locale>
    <resource-bundle>messages</resource-bundle>
  </portlet>
  ...
</portlet-app>

Importante: Sobre o que foi descrito em relação a JSF, o portlet roda no JBoss Portal com JBoss Portlet Bridge.


http://twitter.com/edermag
http://www.yaw.com.br

Wednesday, May 05, 2010

Aprendendo JSF 2.0 com ScrumToys na JavaMagazine - edição 78

Já esta nas bancas a Java Magazine edição numero 78 com artigo (da capa) JSF 2.0: Aprendendo JSF 2.0 com ScrumToys escrito por mim e pelo Vinicius Nunes, instrutor da Globalcode de Floripa.

A proposta do artigo é comentar sobre as mudanças do JSF 2, mas além disso uma preocupação nossa foi colocar conteúdo para quem ainda não teve contato com a tecnologia, seja profissional experinte ou iniciante. É que o artigo ficou um pouquinho grande (rs).

Para mostrar a implementação dos recursos do JSF utilizamos os fontes do ScrumToys, criado justamente para o aprendizado na tecnologia.

No blog da Globalcode fiz uma experiencia, usei o PrimeFaces com JSF 2. Na realidade configurei o PrimeFaces no ScrumToys e utilizei o datatable, fácil, simples e funcionou perfeitamente!



http://twitter.com/edermag
http://www.yaw.com.br

Sunday, April 25, 2010

Configurando o Hibernate 3.5 com Maven

No fim do mês de Março foi lançado o Hibernate 3.5 com novas funcionalidades e a partir dessa versão compatível a JPA2, agora um concorrente ao EclipseLink a implementação de referência. No ScrumToys - projeto da Globalcode exemplo no Netbeans 6.8 - utilizamos o EclipseLink como provider JPA.


O Maven simplifica bastante a vida do desenvolvedor java, isso é indiscutível afinal ficar controlando dependências na mão ficou fora de moda a um tempo. Mesmo quem esta começando usar Java pode tornar essa experiencia mais produtiva, mão na massa sem se preocupar com a burocracia dos jars.

A documentação do Hibernate mostra a configuração exemplo de projeto usando o maven, mas esse mapeamento não funciona por não definir a tag version na dependency, por isso montei um exemplo de pom.xml para utilizar o Hibernate 3.5:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

  <modelVersion>4.0.0</modelVersion>
  <groupId>br.com.globalcode</groupId>
  <artifactId>hibernate-exemplo</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>hibernate-exemplo</name>
  <url>http://maven.apache.org</url>

  <repositories>
    <repository>
        <url>http://repository.jboss.com/maven2/</url>
        <id>hibernate-support</id>
        <layout>default</layout>
        <name>Repository for library Library[hibernate-support]</name>
    </repository>
  </repositories>

  <dependencies>

    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-annotations</artifactId>
        <version>3.5.0-Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>3.5.0-Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-entitymanager</artifactId>
        <version>3.5.0-Final</version>
    </dependency>

    <dependency>
        <groupId>javassist</groupId>
        <artifactId>javassist</artifactId>
        <version>3.8.0.GA</version>
    </dependency>

    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.5.10</version>
    </dependency>

    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.0.5</version>
    </dependency>

    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>3.8.1</version>
        <scope>test</scope>
    </dependency>
  </dependencies>
</project>

Agora é só mandar bala com recursos do hibernate.

http://twitter.com/edermag
http://www.yaw.com.br

Sunday, January 24, 2010

2009 passou voando! Mas relembrando...

O começo de 2009 foi um tanto quanto apreensivo, a expectativa sobre os impactos da crise econômica por aqui eram preocupantes. Ainda bem que as previsões mais pessimistas ficaram pra trás e de uma forma geral conseguimos passar por essa turbulência.

Pra mim 2009 começou com mudança de emprego, quem me conhece sabe que isso é um pouco difícil mim. Novos desafios, ambiente mais complexo, tecnologias diferentes, uma equipe de alto nível técnico entre outros, foram os motivadores para encarar essa nova jornada na Superbid.

Mão na massa, trabalhei com as seguintes tecnologias em diversos projetos:
  • Spring MVC
  • GWT
  • JBoss Portal
  • JBoss Bridge
  • JSF 1.2 c/ RichFaces
  • Python - Genshi
  • Alguns legados em PHP e PL-SQL.

Na Globalcode 2009 foi um ano incrível, repleto de realizações. Trabalhei c/ muitas turmas, conheci pessoas de diferentes perfis e espectativas em relação tecnologia Java. Foram turmas de Academia Java, Academia Web Developer, hands-on e vários minicursos.

A Globalcode promoveu vários eventos para comunidade Java, estive presente em todos em alguns apresentei algum tema:
  • Profissão Java: primeiro evento sobre carreira voltado ao profissional que trabalha ou quer trabalhar com Java, com palestrantes apresentando conteúdo de ponta (ex.: TV Digital) em alto nível para comunidade. Evento gratuito!
  • Open TDC: outro evento gratuito, que aconteceu em Sampa e Floripa! O evento contou com importantes figuras da comunidade de desenvolvimento, com palestras de diversos temas e qualidade de ponta. Apresentei junto com o Rafael Nunes e o Mauricio Leal uma Painel sobre opções RIA p/ Web: JavaFX, Adobe Flex e GWT. O Vinicius apresentou os projetos relacionados a Robótica da Globalcode, além do novo treinamento: Academia do Programador.
  • TDC : o maior e principal evento Java do país, trouxe em sua terceira edição palestrantes internacionais de peso da Sun, Oracle, Google e JBoss. Apresentei uma Lightning Talk sobre as tecnologias open da Google para desenvolvimento Java: GWT e Google Guice. Aqui um resumo do evento que foi fantástico! Em 2009 além de São Paulo e Floripa, o TDC teve sua versão Guanabara, a estreia no Rio de Janeiro.

A Globalcode retomou o Casual Class, que promove um bate-papo descontraído sobre tecnologia c/ Pizza + Cerveja + Vinho. Uma oportunidade de aproximar e fomentar a comunidade! Vários assuntos em pauta, como JavaOne 2009, Robótica, Java EE 6 e Cloud Computing.

Foi no Casual Class de Java EE 6 que fui apresentado ao Scrum Toys, projeto open source da Globalcode demo de JSF2 dentro Netbeans 6.8. Conversei com a Yara sobre algumas coisas interessantes que poderiam ser feitas no projeto como o suporte a bookmarkable, c/ seu apoio abracei a causa colaborando com algumas features. Foi uma experiência enriquecedora, mais detalhes sobre minha participação aqui.

Bastante coisa, mas ainda tem mais. Em 2009 tive a oportunidade de criar e apresentar 2 minicursos:
  • Introdução ao Google Web Toolkit: conteúdo necessário para quem quer saber o que é ou iniciar o desenvolvimento com essa ótima alternativa para Rich Internet Application criado pelo Google.
  • Introdução ao Google GO: apresentando características da nova linguagem do Google, explorando alguns recursos interessantes. O GO seria uma mistura de C++ e Python.

Ainda mais próximo da comunidade de desenvolvimento, foi lançado o Globalcoders, o blog do time Globalcode. Um espaço democrático para Informação + Colaboração + Discussão. Posts relacionados a tecnologia, num formato objetivo, claro e prático em uma linguagem de fácil compreensão. Bloguei sobre Facelets com um post para uso de templates e outro para criação de componentes. Outro post foi um pouco de como funciona o compilador (mágico) do GWT.

Uma dica bem legal é a lista do time Globalcode no twitter. Ótima oportunidade pra ficar pro dentro das novidades que estão rolando e no que estamos trabalhando.

A Globalcode disponibilizou um vídeo bem legal com um resumo, ou melhor uma retrospectiva 2009 e de quão intenso foi esse ano.

E pra encerrar iniciamos a realização de um projeto que há tempos vinhamos planejando, a YaW! Unidade da Globalcode no Grande ABC. Mas isso eu vou descrever em outro post.

Expectativas para 2010 são as melhores, muita determinação e vontade pra enfrentar mais desafios! Trabalho e tesão não faltam.


http://twitter.com/edermag
http://www.yaw.com.br