Criptografando senha com Spring Security

Olá Pessoal,

No post de hoje vamos ver como criptografar senha usando o Spring Security. O objetivo é que a senha do usuário não seja salva no seu BD, e já sabemos o motivo de fazer isso. Não vou entrar nos detalhes.

Lets go

Requisitos

  • Baixe a versão mais recente do SpringSecurity. (Para o post estou usando a versão 3.2.x)

Starting

Há várias soluções na internet, desde usando o Java puro ou usando APIs, Frameworks para criptografar a senha, e para quem está usando o SpringSecurity no projeto tem uma vantagem: já tem uma classe implementada pelo pessoal do Spring que faz isso em 1 linha. Vejamos a classe que criei a seguir para fazer isso. Vejam como é simples:

public abstract class GenerateHashPasswordUtil {       

        private static Object salt; 

        public static String generateHash(String password) {

                MessageDigestPasswordEncoder digestPasswordEncoder = getInstanceMessageDisterPassword();

                String encodePassword = digestPasswordEncoder.encodePassword(password, salt);

                return encodePassword;

        } 

        private static MessageDigestPasswordEncoder getInstanceMessageDisterPassword() {

//informo tipo de enconding que desejo

MessageDigestPasswordEncoder   digestPasswordEncoder = new MessageDigestPasswordEncoder("MD5");

                return digestPasswordEncoder;

        }

        //método que faz a validação  como não usamos salt deixei em null

        public static boolean isPasswordValid(String password, String hashPassword) {

        MessageDigestPasswordEncoder digestPasswordEncoder = getInstanceMessageDisterPassword();

                return digestPasswordEncoder.isPasswordValid(hashPassword, password, salt);

        }

}

 

E aqui a classe de teste que valida alguns cenários:

public class GenerateHashPasswordUtilTest { 

       @Test

       public void testHashWasGenerateWithSuccess() {

             String password="1234";

             assertNotNull(GenerateHashPasswordUtil.generateHash(password));

       }

       @Test

       public void testValidIfPasswordIsValidAfterHashed(){

             String password="brazil";

              String hashPassword =GenerateHashPasswordUtil.generateHash(password);

 boolean expectedValidPassword = GenerateHashPasswordUtil.isPasswordValid(password, hashPassword);

             assertTrue(expectedValidPassword);

       }

       @Test

       public void testPassWordIsNotEqualToHashCodeGenerated(){

             String password = "XPto";

             String passwordhash = GenerateHashPasswordUtil.generateHash(password);

             String passwordTyped = "xPto";

             boolean expectedInvalidPassword = GenerateHashPasswordUtil.isPasswordValid(passwordTyped, passwordhash);

             assertFalse(expectedInvalidPassword);

       } 

}

 

 Simples, não? Se quiser ver o código hash basta imprimir no console.

Abraços, vou ficando por aqui.

Série Dropbox Case com dropbox API

Olá Pessoal

No post de hoje gostaria de compartilhar com vocês uma experiência que tivemos aqui na ITS usando API do DropBox para resolver alguns problemas e facilitar a vida do usuário. Aqui no blog já apresentei para vocês como  usar API do Dropbox, hoje veremos como fazer umas coisas legais na sua aplicação.

Lets go…

Starting…

Case 1

Em um projeto aqui na ITS tínhamos que renderizar imagens em algumas páginas da aplicação e queria fazer isso de maneira simples, fácil e transparente para o usuário final. Considerando que o usuário que coloca as imagens não precisasse conhecer a aplicação, ou melhor, ele poderia nem ter idéia onde aquela imagem que ele criou seria usada, o foco dele era fazer a criação e depois de pronto disponibilizar a imagem em folder chamado de “live” e pronto.  Essa imagem já estaria atualizada na aplicação automaticamente.

Como resolvemos esse problema sem precisar envolver o design com aplicação?

Simples, usando o DropBox.

É isso mesmo. Os designers usam o dropbox para colocar a arte final e uma pasta final onde outro designer faz um review para ver se está ok. Nada de especial aqui, apenas usando o dropbox de maneira tradicional, só que a arte final desse designer ia ser usada na aplicação e precisamos subir a imagem, como fazer?

  • Via upload na aplicação; ou
  • Colocar a imagem direto no servidor e dar uns tapas na app para reconhecer a nova imagem

E o que fizemos?

Usamos dropbox. Para ser sincero eu fui dormir com esse problema, sonhei, e veio o dropbox como solução. Passei alguns dias estudando API e fazendo POC para validar a solução.

A solução

A solução é muito simples: o design vai continuar fazendo o trabalho dele como antes, a aplicação apenas vai buscar imagens na pasta “live” que é uma pasta onde tem a versão final da arte. Daí se o designer fizer alguma alteração nessa imagem, automaticamente ela é atualizada na aplicação. E não precisamos nos preocupar em fazer um novo upload da imagem no servidor  com a versão atualizada, porque há um sync com  a pasta “live”. A esta pasta “live” não é qualquer um que possui acesso, somente Designers mais Seniors tem permissão de escrita nessa pasta. Futuramente vamos facilitar a vida dos designers e implementar um esquema de automatizar os deploys de imagem nessa pasta, mas por enquanto ela ocorre manual. 

O que ganhamos?

– Nada de imagem no Server, então em uma migração de Server não preciso ficar preocupado em copiar imagens e, a depender da quantidade e tipo de negócio, pode demorar a cópia. Quantas imagens você acha que o submarino possui?

– Mais produtividade para o designer. Ele continua focado no trabalho dele fazendo tudo como antes, sem se preocupar onde e quem vai usar aquela imagem;

– Atualização automática da imagem na aplicação. Ou seja, subiu a imagem para pasta “live” já está atualizada na aplicação.

Case 2

Esse aqui também foi fantástico em outro projeto que usava  bastante documentos durante o dia. A vida dos usuários era o Microsoft Word aberto, atualizando os documentos publicados, criando novos  ou corrigindo.  Na versão atual, sempre que um documento é corrigido por uma questão de mudança de lei ou cláusula de contrato, há um prazo de publicação que, a depender da situação, é de até 8hrs a disponibilidade.  Se fosse apenas 1 documento e se acontecesse isso em um período longo, seria fácil, mas não é assim no dia a dia. Hoje o nosso cliente tem que acessar a aplicação, deletar o arquivo anterior e fazer upload do novo. E pior, é interessante manter o antigo como backup, por questão de segurança o delete não remove o arquivo do servidor, apenas move para uma pasta específica. Então o pessoal que trabalha nesses documentos passava boa parte do tempo fazendo upload, fora que às vezes enfrentavam problemas e demora nesse processo, já que tinham arquivos com 10 mb, como projetos com imagens.

E como resolvemos?

Com dropbox API. Os usuários trabalham no dropbox com limitação de acesso, vendo apenas aqueles folders de acordo com o departamento.  Eles não precisam mais se preocupar em fazer upload, apenas trabalham nos docs em uma determinada pasta. Seus superiores podem ir avaliando o documento sendo escrito e já dando feedback. Uma vez concluído, vai para uma pasta que representa o arquivo online e pronto, o arquivo já está atualizado em produção e quem fizer o download já pega o arquivo atualizado.

Fantastico, não?

O que aprendemos?

Nessa solução vimos que apenas saber uma tecnologia não é suficiente; é preciso estar envolvido com o negócio do cliente para chegarmos à solução ideal e sabermos se realmente resolve o problema e agrega valor ao dia a dia do nosso cliente. Não resolver um problema apenas por que temos que resolver, mas buscar como solucionar da melhor forma. É  assim que os profissionais na ITS vivem e respiram todos os dias, e sabemos que negócio & TI não estão separados, e sim juntos. Se você for na API do dropbox é tudo abstrato, o que você vai fazer com ela é uma questão sua. E nós chegamos a essa arquitetura devido ao nível de envolvimento que tínhamos com o negócio, senão ia ser mais uma API disponível como qualquer outra.

Agora temos mais desafios de automatizar alguns trabalhos e permitir que a promoção de uma pasta para outra seja rápida e simples.

Não deixe de conhecer o easyJavaDropboxAPI

Abraços. See ya! 

Série Dropbox Lançamento easyJavaDropboxAPI for Java Developer

Olá Pessoal,

É com muito prazer que venho apresentar pra vocês mais um trabalho da minha start-up: a ITS. Estamos trabalhando bastante com o dropbox aqui para soluções corporativas, e até final do ano devemos lançar uma plataforma para comunidade que vai estar usando a tecnologia. Nesse trabalho percebemos que era necessário criar uma API Java para o dropboxAPI. O motivo? Tínhamos muito trabalho sempre que um projeto ia precisar o dropbox API, ai decidi criar uma API  que chamei de easyJavaDropboxAPI. Como sabemos, qualidade de software, produtividade e manutenção é um desafio sempre e aqui acreditamos bastante no aprendizado contínuo para melhorar o que fizemos ontem, hoje e amanhã.  A seguir explico mais sobre a API e mostro um exemplo simples de uma aplicação Java  + easyJavaDropboxAPI.

lets go…

easyJavaDropboxAPI

Tudo começou de uma simples ideia, e enquanto fui dormir com um problema achei a solução durante os sonhos. Pode acreditar, foi verdade isso. Dei inicio aos estudos e achei a solução na api do dropbox. Infelizmente não posso entrar em detalhes do negócio, pois foi para um projeto corporativo que usamos. Outros projetos chegaram e precisamos da API, então certa hora eu disse “pessoal, precisamos criar uma API Java para o dropbox API. Já temos vários projetos usando e vai ser complicado dar manutenção”. Antes de tornar a easyJavaDropboxAPI pública, ela tinha outro nome, easyDropboxAPI. E por que eu deveria usar a easyJavaDropboxAPI e não diretamente API dropbox API?

É dificil responder a pergunta acima, mas vou mostrar os motivos que nos levou aqui na ITS a termos uma API .

 

Problemas

Produtividade

Estamos crescendo com soluções enterprise usando dropbox API e já estávamos entrando no terceiro projeto quando vimos que o custo de manutenção estava começando a aparecer. No inicio não tínhamos noção do quanto a API poderia ajudar em outros projetos e foi preciso usar em um projeto interno, testar por um período não só a funcionalidade, mas outros fatores de negócio. Por isso que não começamos criando uma API, mas a coisa “virou” e agora queremos ganhar tempo, e com a API é muito simples sair usando em meia dúzia de linhas e em poucos minutos você já está conectado ao dropbox.

Manutenção

Agora não é preciso ficar preocupado com a manutenção do código que conecta com a API do dropbox. Como o dropbox team está sempre atualizando e lançando novas features, temos apenas um único local que vai ter essa feature atualizada e os projetos que precisarem faz o update do .jar para a versão mais recente.

Desenvolvimento Ágil

Na interface temos os métodos mais comuns e objetos do dropbox API que é a base do serviço, então um desenvolvedor novo precisa inicialmente entender pontualmente e à medida que ele for evoluindo vai entrando nos detalhes. Por exemplo, se você pretende listar os arquivos que está no diretório /home do seu dropbox o que precisa ser feito?

1. Saber o que é um token e gerar um;

2. Chamar o método listFiles que retorna todos os arquivos do diretório informado

Cada elemento no list é um arquivo do diretório.

Esses três pontos foram o suficiente para termos API e impactou bastante no dia a dia desenvolvimento.

Vamos ver na prática?

Praticando

1. Crie um simple maven project

2. Adicione a dependência no pom.xml

dropboxeasyjavaapipom

 

<dependency>

<groupId>com.its.api</groupId>

<artifactId>easyJavaDropboxAPI</artifactId>

<version>1.0.0</version>

</dependency>

 

3. Adicione o nosso repositório no pom.xml

<repositories>

<repository>

<id>easyJavaDropboxAPI</id>

<url>https://raw.github.com/ITSStartup/easyJavaDropboxAPI/mvn-repo</url>

<snapshots>

<enabled>true</enabled>

<updatePolicy>always</updatePolicy>

</snapshots>

</repository>

</repositories>

 

4. Crie uma classe Java com o método main

 

public class DropboxMain {

public static void main(String[] args) throws DbxException {

String token = "TOKEN HERE";

EasyJavaDropBoxService easyJavaDropBoxService = new EasyJavaDropBoxServiceImpl(path, token);

List<DbxEntry> listFiles = easyJavaDropBoxService.listFiles();

for (DbxEntry file : listFiles) {

System.out.println(file.name);

}

}

}

 

5. Gere o token seguindo as instruções:

http://apps.camilolopes.com.br/dpboxapiweb

 

6. Rode aplicação e verá:

dropboxconsoleasyapi

 

Pronto, os arquivos que tenho na pasta são listados.

Simples, não?

O projeto de exemplo está disponível no repositório da ITS.

E caso queriam saber mais sobre API, visite o repositório:

https://github.com/ITSStartup/easyJavaDropboxAPI

Abracos. See ya!!!

Série Dropbox Gerando Token dropboxAPI via Web

Olá Pessoal,

O post de hoje é bem rápido. Quero apresentar para vocês o Dropbox API Web.  Mas o que é isso Camilo?

Calma que vou explicar.

Lets go…

Dropbox API Web

É uma versão web que permite gerar um token a partir do app_key e app_secret que é criada no App Console do dropbox quando queremos dar acesso à uma aplicação em nossa conta no dropbox.

Tínhamos um problema  sobre como gerar o token facilmente,  dai criamos uma aplicação web que gera token para app no dropbox. Muitos emails chegaram até mim com dúvidas sobre essa versão e a primeira que postei aqui usando Java Application.

A resposta é que não há diferença entre as aplicações. Fizemos a versão web para ser mais fácil e rápido, sem falar que agora o desenvolvedor não Java pode gerar um token facilmente, já que não precisa saber como rodar um Java Application.

Basicamente é isso. Essa é mais uma constribuição para a comunidade e espero que tenham gostado. Mais novidade está no forno.

E a versão live:

http://apps.camilolopes.com.br/dpboxapiweb

O projeto foi desenvolvido com AngularJS, Spring e Jersey. Sinta-se à vontade em fazer o clone e brincar.  Confira no repositório:

O projeto público está no github:

https://github.com/camilolopes/dpboxapiweb/

Abracos.

Série Dropbox Gerando Token no DropBox API

Olá Pessoal,

No post de hoje vamos ver como gerar um Token para evitar o problema que tivemos no último post, onde cada vez que a aplicação rodar será preciso autorizar novamente para obter o code.

Lets go…

Starting…

Assumindo que você acompanhou e meteu a mão na massa com o post anterior, vou apenas me limitar aqui a resolver o problema que identificamos de evitar múltiplos allow toda vez que a aplicação sobe e precisa conectar com o dropbox.

Development

Crie uma nova classe no projeto (eu chamei de DropBoxGenerateToken). Esse código não fui eu quem criou. Lembro que encontrei nas minhas inúmeras pesquisas para resolver o problema. Acho que tinham umas 40 abas abertas e achei essa solução na discussão do fórum do dropbox developer. Como o código visto no post anterior, se apenas rodar sem entender não vamos conseguir atingir o objetivo. Veja o código a seguir:

public class DropboxGenerateToken{
    public static void main(String[] args)   throws IOException
    {
        // Only display important log messages.

        Logger.getLogger("").setLevel(Level.WARNING); 

        if (args.length == 0) {

            printHelp(System.out);

            return;

        }
        if (args.length != 2) {

            System.err.println("Expecting exactly 2 arguments, got " + args.length + ".");

            System.err.println("Run with no arguments for help.");

            System.exit(1); return;

        } 

        String argAppInfoFile = args[0];

        String argAuthFileOutput = args[1];

        // Read app info file (contains app key and app secret)

        DbxAppInfo appInfo;

        try {

            appInfo = DbxAppInfo.Reader.readFromFile(argAppInfoFile);

        }

        catch (JsonReader.FileLoadException ex) {

            System.err.println("Error reading <app-info-file>: " + ex.getMessage());

            System.exit(1); return;

        }

        // Run through Dropbox API authorization process

        String userLocale = Locale.getDefault().toString();

        DbxRequestConfig requestConfig = new DbxRequestConfig("examples-authorize", userLocale);

        DbxWebAuthNoRedirect webAuth = new DbxWebAuthNoRedirect(requestConfig, appInfo);

        String authorizeUrl = webAuth.start();

        System.out.println("1. Go to " + authorizeUrl);

        System.out.println("2. Click \"Allow\" (you might have to log in first).");

        System.out.println("3. Copy the authorization code.");

        System.out.print("Enter the authorization code here: ");

        String code = new BufferedReader(new InputStreamReader(System.in)).readLine();

        if (code == null) {

            System.exit(1); return;

        }

        code = code.trim();

        DbxAuthFinish authFinish;

        try {

            authFinish = webAuth.finish(code);

        }

        catch (DbxException ex) {

            System.err.println("Error in DbxWebAuth.start: " + ex.getMessage());

            System.exit(1); return;

        }

        System.out.println("Authorization complete.");

        System.out.println("- User ID: " + authFinish.userId);

        System.out.println("- Access Token: " + authFinish.accessToken);

        // Save auth information to output file.

        DbxAuthInfo authInfo = new DbxAuthInfo(authFinish.accessToken, appInfo.host);

        try {

            DbxAuthInfo.Writer.writeToFile(authInfo, argAuthFileOutput);

            System.out.println("Saved authorization information to \"" + argAuthFileOutput + "\".");

        }

        catch (IOException ex) {

            System.err.println("Error saving to <auth-file-out>: " + ex.getMessage());

            System.err.println("Dumping to stderr instead:");

            DbxAuthInfo.Writer.writeToStream(authInfo, System.out);

            System.exit(1); return;

        }

    }

    private static void printHelp(PrintStream out)

    {

        out.println("Usage: COMMAND <app-info-file> <auth-file-output>");

        out.println("");

        out.println("<app-info-file>: a JSON file with information about your API app.  Example:");

        out.println("");

        out.println("  {");

        out.println("    \"key\": \"Your Dropbox API app key...\",");

        out.println("    \"secret\": \"Your Dropbox API app secret...\"");

        out.println("  }");

        out.println("");

        out.println("  Get an API app key by registering with Dropbox:");

        out.println("    https://dropbox.com/developers/apps");

        out.println("");

        out.println("<auth-file-output>: If authorization is successful, the resulting API");

        out.println("  access token will be saved to this file, which can then be used with");

        out.println("  other example programs, such as the one in \"examples/account-info\".");

        out.println("");

    }

}

 

 Feito isso, crie um arquivo com o nome que quiser do tipo .json (o meu chamei de cam.json) e crie um outro chamado de TOKEN. Poderia ser outro nome.

dropboxapiproject

No arquivo cam.json vamos colocar as Keys do app:

{

"key":"7x7k0667",

"secret":"ccc8p2"

}

 

O arquivo TOKEN ficará vazio, mas após executarmos a aplicação será preenchido com o token que será o code usado sempre que precisarmos conectar ao dropbox.

Se tiver usando o Eclipse IDE vá em Run >> Configuration e execute assim:

dropboxruntokenargs

Aguarde o término e abra o arquivo TOKEN:

{

"access_token" : "V5C0NKXurvIAAAAAAAAAAdgoY"

}

Pronto, temos o Token gerado. Agora podemos usá-lo para autenticar e acessar sempre o nosso dropbox sem precisar dar mais allow, mesmo quando a aplicação for finalizada. Voltando ao projeto anterior, devemos fazer essa alteração no método main:

DbxRequestConfig config = new DbxRequestConfig("JavaTutorial/1.0",       Locale.getDefault().toString());

try {

DbxClient client = new DbxClient(config, "V5C0NKXurvIAAAAAAAAAAdgoY");

System.out.println("Linked account: "

+ client.getAccountInfo().displayName);

DbxEntry.WithChildren listing = client.getMetadataWithChildren("/");

System.out.println("Files in the root path:");

for (DbxEntry child : listing.children) {

System.out.println("       " + child.name + ": " + child.toString());

}

}catch (DbxException e) {

e.printStackTrace();

}

catch (Exception e) {

e.printStackTrace();

}

}

 

Observe quanto de código cortamos comparado com a versão do primeiro post.  Claro que poderíamos ler o arquivo TOKEN e ler apenas a chave para obter o valor.  Execute a aplicação e verá que poderá ver todos os seus arquivos sendo listados.

Muito bom, né? Vou ficando por aqui e espero que tenham gostado de mais um post.

Confiram o projeto no Github da ITS: https://github.com/ITSStartup/dropboxapi-example

Abraços. See ya!!!