terça-feira, 28 de julho de 2015

Criando certificados digitais para um ambiente de desenvolvimento/testes

A primeira vez que a gente precisa de um ambiente de desenvolvimento habilitado para SSL a gente nunca esquece.

Cerificados digitais criam uma certa confusão pra quem não está acostumado com eles. E frequentemente o material disponível a respeito é bastante extenso e cheio de detalhes excruciantes. Demais pra quem quer apenas dar o primeiro passo e ter uma ambiente pra testar uma aplicação.

O Que São Certificados Digitais


O Certificado Digital é um mecanismo pelo qual conteúdo pode ser digitalmente assinado. Mais especificamente, ele associa uma identidade (a "pessoa" a quem o certificado pertence) a uma chave pública (e a essa chave púbilca corresponde uma chave privada, usada pelo possuidor do certificado para assinar o conteúdo).

Os certificados são emitidos e assinados por uma Autoridade Certificadora. A própria autoridade certificadora possui um certificado digital e uma chave privada com os quais ela assina todos os outros certificados emitidos por ela.

A maioria dos computadores traz pré-instalada uma série de certificados digitais dessas autoridades. Assim, quando você acessa um site (por exemplo, google.com), é possível verificar se o certificado usado por esse site foi emitido para a "identidade" google.com, e se esse certificado foi assinado por uma autoridade confiável. Esse processo é conhecido como Chain Trust (em alusão à cadeia de certificados usados para assinar outros certificados).

Durante o processo de desenvolvimento, frequentemente nos deparamos com cenários onde precisamos que nossas aplicações estejam preparadas para rodar em ambientes seguros (por exemplo, um webservice que será chamado via https). Para os ambientes de desenvolvimento e testes, pode ser conveniente usar certificados auto-assinados em vez de certificados adquiridos das autoridades certificadoras.

Certificados Auto-Assinados (Self-signed Certificates)


O truque, nesse caso, é criarmos nós mesmos um certificado digital e instalar esse certificado no ambiente de desenvolvimento para ser reconhecido como uma autoridade certificadora confiável. Assim, podemos usar esse certificado para assinarmos nós mesmos certificados que serão tratados, nesse ambiente, como confiáveis (daí o "auto-assinado").

É importante notar que isso cria uma brecha de segurança importante! Qualquer pessoa de posse do seu certificado poderá assinar outros certificados que serão tradados, dentro desse ambiente, como confiáveis.

Como você não vai querer que alguém consiga se passar pelo seu banco, provedor de e-mail... Ou enfim, qualquer outro agente com o qual você comunique informação sensível, é indicado proteger suas chaves privadas com uma senha forte (forte MESMO, leve isso a sério!). Além disso, remova o certificado auto-assinado da lista de certificados confiáveis assim que seus testes terminarem.

E nunca é demais lembrar: NUNCA USE CERTIFICADOS AUTO-ASSINADOS NUM AMBIENTE DE PRODUÇÃO.

A configuração de um ambiente SSL de desenvovlimento envolve os seguintes passos:

Passo 1: Criando a Autoridade Certificadora


Abra o prompt de comando do Visual Studio (como administrador). Navegue até o diretório onde você quer armazenar seus certificados de teste e faça a seguinte chamada ao programa makecert.exe:

makecert -n "CN=DevTestAuthority" -cy authority -a sha1 -sv "DevTestAuthority.pvk" -r "DevTestAuthority.cer"

Os parâmetros que passamos para o makecert quando emitimos esse certificado são:



-n: A identidade (ou nome) do detentor do certificado. Para um website, deve corresponder exatamente ao domínio do site.
-cy authority: Especifica que estamos criando um certificado para uma autoridade certificadora
-a sha1: Especifica o algoritmo de criptografia empregado (SHA1, nesse caso)
-sv: A chave privada que será utilizada. Caso não exista a chave privada especificada, uma nova será criada.
-r: Emite um certificado auto-assinado, ou seja, nenhum outro certificado será usado pra assinar este. Ele será a "raiz" da cadeia de certificados
DevTestAuthority.cer: O nome do arquivo do certificado

Ao executar esse comando pela primeira vez, será pedida uma senha para a chave privada. Lembre de fornecer uma senha forte!

Passo 2: Instalando o Certificado Recém Criado Para Uma Autoridade Certificadora Confiável


Em Iniciar > Executar, busque por mmc.exe.



Agora, no menu "File > Add/Remove Snap-In"



Escolha "Certificates" e clique na seta para a direita para adicionar este Snap-In



Na sequência, uma janela de diálogo solicitará para qual computador você deseja gerenciar os certificados. Deixe selecionada a opção "Local Computer" e clique em "Finish".

Você verá o painel abaixo. Agora, vamos adicionar nosso certificado a "Trusted Root Certification Authorities", para que ele passe a ser reconhecido em nosso computador local como o certificado de uma autoridade certificadora confiável. Então, poderemos usar este certificado para assinar nossos certificados de desenvolvimento.

Clique com o botão direito sobre Trusted Root Certification Authorities > All Tasks > Import. Isso abrirá o diálogo para importar nosso certificado. Siga os passos na tela, e quando perguntado sobre o arquivo do certificado, escolha o arquivo DevTestAuthority.cer que criamos usando a ferramenta makecert:





Após isso, nosso certificado será exibido na lista de autoridades confiáveis.



Agora podemos emitir nossos certificados de desenvolvimento e assiná-los com nossa Autoridade Certificadora.

Passo 3: Emitir um Certificado e Assiná-lo com a Autoridade Certificadora


Para isso, voltarmeos ao markecert com o seguinte comando:

makecert -n "CN=seudominio.com" -ic "DevTestAuthority.cer" -iv "DevTestAuthority.pvk" -a sha1 -sky exchange -pe -sv "meudominio.com Private Key.pvk" "meudominio.com.cer"



Durante, você será perguntando sobre a senha do "Issuer" (emissor, ou autoridade certificadora), que é a senha que usamos para criar o certificado anterior. Também será pedida uma senha para a chave privada do certificado que estamos criando agora. Novamente, escolha uma senha forte.

Dessa vez, alguns dos parâmetros são um pouco diferentes dos que usamos para criar o certificado da Autoridade Certificadora:

-n: O nome do certificado. No caso de websites, é o nome do domínio (ex: meudominio.com)
-ic: O certificado que usaremos como Autoridade Certificadora, para assinar o novo certificado
-iv: O arquivo que contém a chave-privada da autoridade certificadora (foi criado no passo anterior)
-a sha1: O algoritmo de criptografia. Estamos usando sha1 neste exemplo
-sky exchange: Especifica que nosso certificado pode fazer troca de chaves (key exchange)
-pe: Especifica que a chave privada do certificado será exportável
-sv: A chave privada que será usada (ou criada, caso ainda não exista)
meudominio.com.cer: O nome do arquivo que conterá o certificado

Passo 4: Instalação do Certificado Auto-Assinado


O último passo será combinar a chave privada e o certificado recém criados num único arquivo PFX, usando a ferramenta pvk2pfx:

pvk2pfx -pvk "meudominio.com Private Key.pvk" -spc "meudominio.com.cer" -pfx "meudominio.com.pfx" -pi SenhaDaPrivateKey

Usando os seguintes parâmetros:

-pvk: O arquivo da chave privada do certificado
-spc: O arquivo do certificado que será colocado no arquivo PFX
-pfx: O nome do arquivo PFX que será criado
-pi: A senha da chave privada do certificado (a mesma que você usou quando criou o certificado usando o makecert).



Agora, basta importar o arquivo PFX criado para sua Store local de certificados, um procedimento parecido com o que usamos para importar o certificado da Autoridade Certificadora. Veja abaixo os passos:

Abra o assistente de importação, dessa vez na guia "Personal" em vez de "Trusted Root Certification Authorities":


Os passos serão os mesmos de antes, mas em vez de escolher o arquivo .cer, dessa vez vamos importar o arquivo de extensão .pfx:


O assistente perdirá a senha do certificado. Conclua os passos do assisnte e PRONTO! Agora você tem uma autoridade certificadora confiável e um certificado emitido por ela para uso no seu ambiente de testes e desenvolvimento :)


segunda-feira, 20 de julho de 2015

Usando os elementos semânticos do HTML 5

Uma das primeiras diferenças que você vai encontrar quando comparar o HTML5 com as versões anteriores é a presença de elementos semânticos em vez de apenas elementos estruturais.

A função desses elementos é tão simples quanto o próprio nome sugere: ao declarar elementos no seu documento, os nomes dos elementos também expressam o significado (ou função) deles.

Em vez dos velhos elementos como <div> e <span> (que continuam lá, você pode usá-los como sempre usou), entram novas tags como <article>, <header> ou <footer>.

Por quê usar as tags semânticas?


Observe os dois trechos de código abaixo:

Sem tags semânticas:

<body>
    <div id="header">...</div>
    <div id="menu">...</div>
    <div class="articleContent">...</div>

    <div class="advertise">...</div>
    <div class="copyright">...</div>
</body>

Com tags semânticas:


<body>
    <header>...</header>
    <nav>...</nav>
    <article>...</article>

    <aside>...</aside>
    <footer>...</footer>
</body>

Num exemplo tão simples não parece grande coisa. Mas mesmo ele nos permite identificar um pouco da importância das tags semânticas:
  • Código mais fácil de ler. O nome das tags identifica seu objetivo na página. Fica muito mais fácil entender a intenção de um determinado trecho de html.
  • Otimização para search engines. Elementos semânticos tornam sua página mais fácil de ler e indexar, pois é mais fácil distinguir títulos, subtítulos e conteúdos relevantes.
  • Otimização para leitores de tela. Softwares de leitura de tela conseguem diferenciar melhor entre títulos, seções, conteúdos e elementos estruturais da página com o uso das tags semânticas.

Usando os Elementos Semânticos


Vamos agora entender quais são os elementos semânticos do HTML5 e suas respectivas funções. No final, veremos um exemplo completo, usando todos os elementos em seu contexto.

<header>


Representa o título ou cabeçalho de uma página ou de uma seção dentro de uma página.

<hgroup>


Um grupo de headers.

<nav>


Usando para agrupar elementos de navegação. Por exemplo, um menu a ser apresentado na parte superior da tela.

<article>


Um artigo compreende uma área principal da página, com conteúdo relevante. Um exemplo de candidato a article é um post de um blog. Uma mesma página pode conter vários articles (de fato, qualquer elemento semântico pode aparecer várias vezes numa mesma página).

<section>


Representa uma unidade de conteúdo distinto. Se o post de blog que criamos com o elemento article contém diversas partes distintas, cada uma delas pode ser representada por uma section.

<figure>


Adivinha? Representa ma figura.

<figcaption>


Representa a legenda de um elemento figure.

<aside>


Compreende pequenas seções de conteúdo que não fazem parte do fluxo principal da página. Por exemplo, um anúncio.

<mark>


Define conteúdo que deve ser destacado. É a caneta marca-texto verde florescente do HML5.

<progress>


Mostra o progresso de uma tarefa.

<footer>


Representa o rodapé de uma seção da página ou da própria página.

Juntando as Peças: Um exemplo completo

e feio. Vai ficar bonito num post subsequente, quando falarmos de CSS3!

Nesse exemplo, criamos uma página que engloba todos os elementos semânticos. Salve esse código num arquivo .html e abra em diversos browsers diferentes. Veja que alguns browsers oferecem uma formatação padrão para alguns desses elementos, buscando destacar a função semântica de cada um dentro da página.

É claro que essa formatação padrão é bastante pobre em comparação com o que esperamos de uma página pronta para produção. Mas leve em consideração que da mesma forma que o browser é capaz de distinguir o "significado" das diferentes partes da página usando a semântica das tags, mecanismos de busca e leitores de tela também serão capazes de fazê-lo com a mesma facilidade.

Chega de enrolação. Hora do código:

<!DOCTYPE html>
<html>

<head>
<meta charset="utf-8"/>
<title>Um Exemplo de Tags Semânticas</title>
</head>

<body>

<header>
<h1>Esse é o título da página!</h1>
</header>

<nav>
<a href="#">Home</a> |
<a href="#">Link 1</a> |
<a href="http://www.vidadeprogramador.com.br">Pra Descontrair...</a>
</nav>

<article>
<header>
<hgroup>
<h2>Título Principal de um Arigo Qualquer</h1>
<h3>Junto com um subtítulo</h3>
</hgroup>
</header>
<section>
<header>
<h4>Título da Primeira Seção do Artigo</h4>
</header>
<p>Um parágrafo da seção que contém <mark>um trecho de texto que deve ser destacado!!!!!</mark>
<p>Um outro parágrafo, que contém uma figura (veja!)
<figure>
<img src="http://www.pudim.com.br/SiteBuilder/UploadUsers/pudim.com.br/pudim.jpg" alt="Conheça o pudim!">
</figure>
<figcaption>
<a href="http://www.pudim.com.br/">Conheça o Pudim!</a>
</figcaption>
</p>
</section>
<section>
<header>
<h4>Título da Segunda Seção do Artigo</h4>
</header>
<p>
Lorem ipsum sit dolor amet...
</p>
</section>
<footer>
Algumas notas de rodapé para nosso artigo
</footer>
</article>

<aside>
<p>
Você pode colocar uns anúncios aqui...
</p>
<p>
... ou uma barra de progresso!!! <progress value="22" max="100"></progress> (mas por quê você faria isso???)
</p>
</aside>

<footer>
E finalmente um rodapé para nossa página... :) <br/>
(aquela mensagem de copyright que ninguém vai ler pode vir aqui!)
</footer>

</body>

Uma nota sobre DOCTYPE e Charset


Repare que na especificação do HTML5 a declaração do DOCTYPE no começo da página ficou muito mais simples. Para um comparativo das declarações de DOCTYPE entre as diferentes especificações do HTML veja o site do W3Schools aqui!

quarta-feira, 13 de junho de 2012

Dicas rápidas de jQuery: Selecionando múltiplas classes de uma vez

Considere uma página com os seguintes elementos:

<input type="text" class="classe1" id="txtNome" />
<input type="text" class="classe2" id="txtSobrenome" />
<input type="text" class="classe3" id="txtTelefone" />
<input type="text" class="classe4" id="txtEndereco" />
<input type="text" class="classe1 classe2 classe3" id="txtEmail" /> 
<input type="text" class="classe1 classe2 classe4" id="txtEmail" />


Por vezes, em nossos projetos, queremos aplicar uma regra, efeito ou comportamento a elementos de várias classes ao mesmo tempo. Imagine que queremos, no exemplo acima, limpar o conteúdo de todas as caixas de texto que implementem as classes: classe1, classe2 e classe3.

Em vez de escrever:

$('classe1').val('');
$('classe2').val('');
$('classe3').val('');

podemos usar um seletor com diversas classes, reduzindo o código acima a:


$('classe1, .classe2, .classe3').val('');

E caso queiramos limpar todos os elementos que implementam, ao mesmo tempo, as classes classe1, classe2 e classe3, utilizamos a seguinte sintaxe:

$('classe1.classe2.classe3').val('');

No primeiro exemplo limpamos o conteúdo de todas as caixas de texto, exceto a txtEndereco, porque à exceção dela, todas implementam pelo menos uma das três classes que informamos ao seletor.

Já no segundo caso, apenas a txtEmail será selecionada, porque é a única que implementa as três classes simultaneamente.

sexta-feira, 6 de janeiro de 2012

Enviando e-mail com C#

Olá pessoal!

Neste post, vamos mostrar como enviar uma mensagem de e-mail utilizando C#.

As classes que utilizaremos estão nos namespaces System.Net e System.Net.Mail. Tenha certeza de tê-las referenciado:

using System.Net;
using System.Net.Mail;

No exemplo, vou usar as configurações para envio usando uma conta do GMail. Vamos ao código:

    SmtpClient client = new SmtpClient("smtp.gmail.com", 587);
    client.EnableSsl = true;

    MailAddress remetente = new MailAddress("seu.email@gmail.com", "Seu Nome");
    MailAddress destinatario = new MailAddress("email.do.destinatario@qualquercoisa.com", "Nome do Destinatário");

    MailMessage message = new MailMessage(remetente, destinatario);
    message.Body = "Acesse gustavosiqueira.blogspot.com";
    message.Subject = "Enviando email com C#";

    NetworkCredential credential = new NetworkCredential("seu.email@gmail.com", senha.do.email" );
    client.Credentials = credential;
   
    client.Send(message);

Seguindo o código passo-a-passo:

  • Criamos uma instância da classe SmtpClient, que implementa o envio de e-mails pelo protocolo SMTP. No construtor, passamos o endereço do servidor de saída e a porta de saída que nosso serviço de e-mail utiliza (smtp.gmail.com e porta 587, para o caso do GMail);
  • Como o GMail requer o uso de SSL para envio de e-mails, definimos a propriedade EnableSSL para true;
  • Criamos dois objetos MailAdress (endereço de email). Um com os dados do remetente e outro com os dados do destinatário;
  • Criamos um objeto MailMessage, que representa a mensagem de e-mail propriamente dita. No construtor já podemos passar os MailAddress do remetente e do destinatário. O corpo da mensagem foi definido na propriedade Body, e o assunto do e-mail na propriedade Subject;
  • Criamos uma NetworkCredential com login e senha de nossa conta de e-mail. Passamos essas credenciais ao nosso objeto SmtpClient;
  • Por fim, usamos o método Send do SmtpClient para enviar a mensagem.

E está feito! Em breve, o post que fiquei devendo sobre introdução ao Ajax com Asp.Net!

Abraços a todos!

terça-feira, 27 de dezembro de 2011

Asp.net com EntityFramework: Gerenciando o ciclo de vida do ObjectContext

Olá, pessoal!

Uma dúvida relativamente comum pra quem está começando a usar o Entity Framework em projetos Asp.Net diz respeito ao gerenciamento do ciclo de vida dos objetos ObjectContext.

Qual é a forma correta de gerenciá-los? Em que momento devem ser criados ou destruídos? Por um lado, é muito custoso instanciar um novo contexto toda hora. Você não poderia, por exemplo, criar um a cada método que requeira o uso de um ObjectContext. Por outro, também não podemos simplesmente criar um ObjectContext e deixá-lo viver na memória por toda a sessão de um usuário, ou por todo o ciclo de vida da aplicação.

Uma abordagem amplamente aceita para balancear a quantidade de objetos criados e o tempo de vida de cada um deles é criar um ObjectContext para cada request do Asp.net. Assim, no início de cada request instanciamos um novo ObjectContext, e o destruímos no final da request.

Fazemos isso adicionando um HttpModule ao nosso projeto, e injetando a lógica de criação/destruição dos ObjectContexts nos eventos BeginRequest e EndRequest.

Abaixo, um exemplo dessa implementação. Lembre-se de referenciar o namespace System.Web.

public class ContextManagerModule : IHttpModule
{

    public void Init(HttpApplication application)
    {
        application.BeginRequest += new EventHandler(BeginRequestHandler);
        application.EndRequest += new EventHandler(EndRequestHandler);
    }

    public void BeginRequestHandler(object sender, EventArgs e)
    {
        HttpContext.Current.Items["__DATACONTEXT"] = new EFContext();
    }

    public void EndRequestHandler(object sender, EventArgs e)
    {
        ((EFContext)HttpContext.Current.Items["__DATACONTEXT"]).Dispose();
    }

    public void Dispose() { }
}

Nesse exemplo, EFContext é nossa classe que implementa o ObjectContext do EntityFramework. Substitua pelo nome do ObjectContext do seu projeto.

Agora, sempre que tiver que acessar o ObjectContext, pode fazê-lo assim:

var exemplo = ((EFContext)HttpContext.Current.Items["__DATACONTEXT"]);


Não declare esta variável dentro de um using, pois não queremos que o objeto seja destruído antes do final da request.

O handler que criamos para o evento BeginRequest garante que um ObjectContext ficará disponível para uso ao longo do ciclo de vida de cada nova request.

Já o handler que adicionamos no evento EndRequest da aplicação garantirá que o ObjectContext será destruído logo ao final da request.

sexta-feira, 23 de dezembro de 2011

Ajax Framework Failed to Load? Sys is not defined? WebForm_InitCallback is not defined? E agora?

Como começou

Tem um post fresquinho saindo do forno pra esse final de semana, que será uma introdução ao Ajax com Asp.Net.

Mas antes vou comentar um problema que me deu uma baita dor de cabeça essa semana. Vi mil soluções possíveis na internet e nenhuma funcionou pra mim.

Algumas páginas começaram apresentar os seguintes erros:
  • Ajax Framework Failed to Load
  • Sys is not defined
  • WebForm_InitCallback is not defined
Uma investigação rápida mostrou que o WebResources.axd estava retornando conteúdo em branco, em vez dos scripts que normalmente esperaríamos.

As fontes possíveis do problema, conforme discutidas em vários fóruns e blogs, apontavam principalmente para:
  • WebFarms;
  • Compressão de conteúdo;
  • Mapeamento incorreto ou inexistente da extensão .axd no IIS;
  • Presença de um HttpModule customizado que estivesse interceptando as requests e "desviando o tiro do alvo" para as url's com extensão .axd;
  • Data/Hora incorretas no servidor (pois é, isso também pode causar esse problema...);
  • Ausência da dll do AjaxToolkit na pasta \bin da aplicação
  • Instalação corrompida do .Net Framework, sendo necessário reparar a instalação

 Investiguei cada ponto e nenhum desses era aplicável ao projeto que eu tinha em mãos...

Como eu resolvi

Antes de tudo, "resolvi" significa "contornei". Meus .axd's continuam sem retornar nada...

O que eu fiz, nesse caso, foi alterar a propriedade "EnableCDN" para true em todos os meus objetos ScriptManager.

Com isso, em vez de fazer o download dos scripts a partir do meu próprio IIS (usando os WebResource.axd e ScriptResource.axd), meus objetos ScriptManagers vão procurá-los, antes, na CDN da Microsoft, e baixam os scripts a partir de lá.

quarta-feira, 14 de dezembro de 2011

jQuery DataTables Plugin

Olá, pessoal!

Pra “aquecer o motor” nesse primeiro post do blog, vamos falar um pouco sobre um plugin muito útil para jQuery, o DataTables.

O DataTables fornece controles avançados de interação para tabelas em HTML. Tudo com umas poucas (pouquíssimas MESMO) linhas de Javascript.

Algumas coisas que o DataTables faz por você (e muito bem):
  • Paginação de resultados
  • Filtragem de dados na tabela
  • Ordenação
Além disso, o framework é altamente flexível, e cada detalhe é altamente customizável.

O DataTables também dá suporte ao ThemeRoller, do jQuery UI. Com isso, você pode aplicar às suas tabelas quaisquer temas do ThemeRoller - desde os “pré-fabricados” até os customizados, construídos por você. O que vai poupar um bocado do tempo que você passaria escrevendo CSS.

Mão na massa

Chega de conversa. Nada mais explicativo que algumas linhas de código pra mostrar o poder e a versatilidade do DataTables.

Antes de mais nada, você vai precisar baixar a versão mais recente do plugin no site oficial do DataTables: http://datatables.net/download/

Agora, crie uma página simples (digamos... HelloDataTables.html), com o seguinte código:

<html>
    <head>
        <title>Hello DataTables</title>
    </head>

    <body>
    <table id="tabela">
        <thead>

        <tr>
            <th>Nome</th>
            <th>Endereço</th>
            <th>Telefone</th>
            <th>E-mail</th>
        </tr>

    </thead>

    <tbody>
        <tr>
            <td>Fulano da Silva</td>
            <td>Rua do Fulano da Silva, 1234</td>
            <td>(11) 1111-111</td>
            <td>fulano@exemplo.com</td>
    </tr>
    <tr>
            <td>Beltrano Oliveira</td>
            <td>Rua do Beltrano, 4321</td>
            <td>(22) 2222-2222</td>
            <td>beltrano@exemplo.com</td>
    </tr>
    <tr>
            <td>Ciclano de Tal</td>
            <td>Rua do Ciclano, 100</td>
            <td>(33)1234-5678</td>
            <td>ciclano@exemplo.com</td>
        </tr>
    </tbody>
</table>
</body>
</html>

Sua página deve ficar parecida com isso:


Voilá! Temos uma tabela com 3 linhas... 4 colunas... e nenhuma graça! Vamos incrementá-la um pouco usando o DataTables.
Primeiro, no final da página (entre as tags </body> e </html>) vamos referenciar os scripts do jQuery, jQuery UI e o DataTables:

</body>
     <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" language="javascript" type="text/javascript"></script>

    <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js" language="javascript" type="text/javascript"></script>

    <script src="jquery.dataTables.min.js" language="javascript" type="text/javascript"></script>

</html>

Certifique-se de copiar o arquivo jquery.dataTables.min.js para o mesmo diretório onde está o HelloDataTables.html. Este arquivo é parte do pacote que você baixou no site do DataTables. No arquivo compactado com o DataTables, ele se encontra no diretório media\js.
Logo após essas referências criaremos o seguinte script:

<script language="javascript" type="text/javascript">

    $(document).ready(function() {

        $('#tabela').dataTable();

    });

</script>
 
Abaixo um screenshot de como vai ficar nossa página:


Perceba que temos um campo de filtro, e podemos controlar também quantos resultados queremos em cada página. Podemos ordenar os resultados clicando nos cabeçalhos de cada coluna.
Temos paginação, ordenação dinâmica dos resultados e filtro, e escrevemos apenas uma linha de Javascript, invocando o método dataTable() para nossa tabela! 

Melhorando a aparência

Voilá outra vez! Agora temos como ordenar, filtrar e paginar nossa tabela. Que continua não tendo graça nenhuma. Então vamos partir pra outra funcionalidade do DataTables e aplicar um tema do ThemeRoller.
Vamos usar um tema pronto. Para isso, vá até http://jqueryui.com/themeroller/#themeGallery
Na lista de temas que aparece do lado esquerdo da página, clique no botão “Download” de qualquer um deles. Em nosso exemplo, vamos usar o tema “UI Lightness”, mas você pode seguir o tutorial com qualquer um deles.
Vamos incluir a seguinte linha dentro do head da HelloDataTable.html para referenciar a folha de estilos customizada com o nosso tema:

    <link href="jquery-ui-1.8.16.custom.css" rel="stylesheet" type="text/css" />

Este arquivo, jquery-ui-1.8.16.custom.css, está no arquivo compactado que você baixou com seu tema do ThemeRoller. Procure-o em \css\ui-lightness (troque "ui-lightess" pelo nome do seu tema, caso tenha baixado outro).
E vamos modificar a linha que cria nosso DataTable. Onde estava:

$('#tabela').dataTable();

Vai ficar:

$('#tabela').dataTable({
    "bJQueryUI": true
});

Definir o parâmetro “bJQueryUI” para “true” instrui o DataTables a utilizar os temas do ThemeRoller.
Começa a ficar apresentável, mas ainda está estranho...
Vamos fazer alguns ajustes em nossa página. Primeiro, vamos criar um arquivo chamado exemplo.css, e vamos estilizar um pouco nossa página. O conteúdo do arquivo será o seguinte:

*

{
font-family: Sans-Serif;
font-size: 10pt;
}


body
{
margin: 20px 0 0 0;
padding: 0;
text-align: center;
}

#wrapper
{
width: 700px;
margin: 0px auto;
text-align: left;
padding: 5px;
}

#tabela
{
width: 700px;
}

E vamos incluir uma referência a nosso arquivo CSS no cabeçalho da página, logo abaixo da referência à folha de estilos do nosso tema.

<link href="exemplo.css" rel="stylesheet" type="text/css" />

Finalmente, vamos envolver todo o conteúdo da página com um <div>.

<div id="wrapper">
… conteúdo da página ...
</div>

Agora, nossa página tem a seguinte aparência:

Abaixo, todo o código-fonte da página até agora:

<html>
<head>
<title>Hello DataTables</title>
    
<link href="jquery-ui-1.8.16.custom.css" rel="stylesheet" type="text/css" />

<link href="exemplo.css" rel="stylesheet" type="text/css" />
  
</head>

<body>

    <div id="wrapper">

        <table id="tabela">
            <thead>

                <tr>
                    <th>Nome</th>
                    <th>Endereço</th>
                    <th>Telefone</th>
                    <th>E-mail</th>
                </tr>

            </thead>

            <tbody>
                <tr>
                     <td>Fulano da Silva</td>
                     <td>Rua do Fulano da Silva, 1234</td>
                     <td>(11) 1111-111</td>
                     <td>fulano@exemplo.com</td>
                </tr>
                <tr>
                     <td>Beltrano Oliveira</td>
                     <td>Rua do Beltrano, 4321</td>
                     <td>(22) 2222-2222</td>
                     <td>beltrano@exemplo.com</td>
                </tr>
                <tr>
                     <td>Ciclano de Tal</td>
                     <td>Rua do Ciclano, 100</td>
                     <td>(33)1234-5678</td>
                     <td>ciclano@exemplo.com</td>
                </tr>
            </tbody>
        </table>
    </div>
</body>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" language="javascript" type="text/javascript"></script>

<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js" language="javascript" type="text/javascript"></script>

<script src="jquery.dataTables.min.js" language="javascript" type="text/javascript"></script>

<script language="javascript" type="text/javascript">
     $(document).ready(function() {
          $('#tabela').dataTable({
          "bJQueryUI": true
     });
});
</script>
</html>

Algumas melhorias a mais...

Além do parâmetro “bJQueryUI” que usamos antes, o DataTables expõe uma infinidade de outros parâmetros que podemos utilizar para modificar a aparência e o comportamento de nossas tabelas.
Abaixo, vamos usar alguns deles para completar nosso exemplo.
Podemos controlar a forma como o DataTables paginará nossas tabelas. Alguns parâmetros importantes nessa configuração são:
  • bLengthChange: Define se o usuário pode alterar a quantidade de registros exibidos por página. Vamos usar “false” em nosso exemplo;
  • bfilter: Define se os resultados podem ser filtrados. Vamos deixar os filtros habilitados em nosso exemplo;
  • iDisplayLength: Define a quantidade de registros exibidos por página. Vamos usar “10” em nosso exemplo;
Você provavelmente notou um problema com nossa tabela... Todas as mensagens estão em inglês! O DataTables expõe várias propriedades para internacionalização, de modo que possamos customizar ou traduzir essas mensagens conforme a nossa necessidade.
Vamos a algumas dessas propriedades:
  • oLanguage.sSearch: Define o label do campo de busca (filtro) da tabela. Vamos usar “Pesquisar” em nosso exemplo.
  • oLanguage.sInfo : Mostra quantos resultados estão sendo exibidos na tabela.
  • oLanguage.sEmptyTable : Mensagem que será mostrada se a tabela não tiver registros.
  • oLanguage.sInfoFiltered: Mensagem que notifica que os resultados da tabela foram filtrados. Vamos deixar em branco em nosso exemplo.
Portanto, o construtor de nossa tabela ficará assim:
$('#tabela').dataTable({

    "bJQueryUI": true,

    "bLengthChange" : false,

    "iDisplayLength" : 10,

    "oLanguage": {

        "sInfo": "Mostrando registros de _START_ a _END_ de um total de _TOTAL",
        "sInfoEmpty": "Nenhum registro para exibir",

        "sSearch" : "Pesquisar",

        "sInfoFiltered" : ""

    }

});


Agora, nossa página deve ter a seguinte aparência:

Para saber mais...

Esta é apenas uma pequena amostra das capacidades do DataTables. Você pode fazer muito mais com este plugin.
A documentação do DataTables é bem completa, e vale a pena gastar algum tempo vendo as propriedades e eventos disponíveis, e testando alguns deles para incrementar nosso exemplo.
Até a próxima!