Microsoft Anti-Cross Site Scripting Library V1.0

by Israel Aece 1. March 2006 09:21

Há poucos dias atrás, a Microsoft lançou o "Anti-Cross Site Scripting Library V1.0". Trata-se de uma biblioteca que substitui os métodos HttpUtility.HtmlEncode e HttpUtility.UrlEncode e, com a mesma finalidade, de evitar ataques XSS nas aplicações Web/ASP.NET.

A diferença é que com esta nova biblioteca, os métodos trabalham com os caracteres permitidos "white-listing" ao invés dos caracteres não permitidos "black-listing", como é o caso dos métodos da classe HttpUtility. Isso fará com que, ao chamar os métodos, o que não estiver contido dentro deste "conjunto" de caracteres válidos, será codificado. Para maiores informações a respeito, façam o download e analisem o documento que vem junto com o pacote.

Tags:

ASP.NET | Security

Post Cache Substitution

by Israel Aece 12. February 2006 09:27

Quando colocamos uma determinada página em OutputCache nas versões 1.x do ASP.NET, tínhamos/temos problemas quando existem nesta página, regiões dinamicas que, devem ser sempre atualizadas quando um Refresh ou PostBack acontecer.

Com este cenário, ou teríamos que optar por não deixar a página em OutputCache, ou criar UserControls (arquivos ASCX) para habilitar o Fragment Caching e assim, atualizar essas informações dinamicas. No ASP.NET 2.0 foi introduzido um novo conceito chamado de Post Cache Substitution. Trata-se de um controle chamado Substitution, que temos à disposição na ToolBox do Visual Studio .NET 2005. Devemos arrastá-lo para o local da página onde o conteúdo será dinamico e, através da propriedade MethodName do mesmo, apontamos para um método estático que, obrigatoriamente deverá estar de acordo com o delegate HttpResponseSubstitutionCallback. Este será o método qual o ASP.NET executará sempre.

Abaixo é exibido um exemplo simples que ilustra o funcionamento desta nova feature:

<%@ OutputCache Duration="60" VaryByParam="none" %>
....
<asp:Substitution
     ID="Substitution1" 
     runat="server" 
     MethodName="GetCurrentDateTime" />

<asp:Label
     ID="Label1" 
     runat="server" 
     Text="Label">
</asp:Label>

E no CodeBehind:

    protected void Page_Load(object sender, EventArgs e)
    {
        this.Label1.Text = DateTime.Now.ToString();
    }

    public static string GetCurrentDateTime(HttpContext ctx)
    {
        return DateTime.Now.ToString();
    }

Esse código fará com que a página fique em OutputCache durante 60 segundos, porém a região da página que é determinada pelo controle Substitution, sempre será atualizada.

Tags: ,

ASP.NET

Encriptando seções do Web.Config

by Israel Aece 12. February 2006 09:26

No ASP.NET 2.0, temos uma nova versão do utilitário de linha de comando aspnet_regiis.exe. Consequentemente temos novas funcionalidades adicionadas a ele e, uma delas, é a possibilidade de encriptarmos seções do arquivo Web.Config de uma determinada aplicação ASP.NET. A sua sintaxe para uso é simples:

C:\>aspnet_regiis -prov DataProtectionConfigurationProvider -pef appSettings C:\WebSite1

A seguir a explicação dos parametros:

-prov: indica o provider que quer utilizar para encriptar a seção.
-pef + seção + diretório físico: indica a seção do arquivo Web.Config que será encriptada, fornecendo em seguida, o caminho físico do diretório da aplicação.

Tags:

.NET Framework | ASP.NET | Security

Livro ASP.NET 2.0

by Israel Aece 1. February 2006 09:28

Bem, como já comentei muitas vezes por aqui, já está disponível em algumas livrarias nacionais o Livro de ASP.NET 2.0 do Luis Abreu. Eis aqui uma das opções.

Tags:

ASP.NET | General

Client Side Callbacks

by Israel Aece 9. January 2006 14:16

Um dos principais desafios dos desenvolvedores de aplicações Web é construir uma aplicação intuitiva e ao mesmo tempo dinâmica, tornando a aplicação o mais próximo possível do "mundo Windows". Como essa aproximação é sempre comparada pelos clientes, o principal ponto negativo que as pessoas que estão migrando suas aplicações Windows para aplicações Web encontram é o fato de quando submetemos algo para ser processado no servidor, a página causa um Refresh, ou seja, ela é totalmente reconstruída.

Com esse comportamento as aplicações Web foram bastante crucificadas quando comparadas as aplicações Windows tradicionais. Com a necessidade de ter algo ainda mais dinâmico, algumas tecnologias foram criadas em paralelo as de desenvolvimento dinâmico de sites, tornando as aplicações Web ainda mais interativas. Uma das primeiras tecnologias que apareceram para preencher essa lacuna foi o Remote Scripting, que fornece uma infraestrutura para invocar método server-side, ou seja, que rodam no servidor sem a necessidade de submeter a página. Essa tecnologia utiliza Java Applets para fazer a comunicação com o servidor, comunicando através de protocolo HTTP. Há também opções onde não são necessários Applets para isso, utilizando apenas JavaScript e DHTML, como podemos ver neste componente.

Atualmente, se fala bastante em uma tecnologia chamada AJAX (Asynchronous JavaScript and XML), a qual tem a mesma finalidade da anterior e utiliza o objeto XMLHTTPRequest para a comunicação entre o browser cliente e o servidor. Na versão ASP.NET 2.0, a Microsoft implementou o que chamamos de Client-Side Callbacks. Essa é uma opção paleativa que a Microsoft introduziu no ASP.NET 2.0; paleativa porque a própria Microsoft trabalha atualmente em um projeto chamado Atlas, qual brevemente estará disponível. Esse projeto trará aos desenvolvedores ASP.NET uma facilidade enorme no desenvolvimento, encapsulando boa parte do código Javascript que é requerido nestes cenários. Inclusive serão fornecidos diversos controles Drag & Drop, permitindo assim a codificação declarativamente.

Semelhante ao Remote Scripting, os Client-Side Callbacks permitem chamar um código qualquer VB.NET ou C#, que corre no servidor, através do cliente, sem a necessidade de atualizar a página. A única diferença é que ele utiliza XmlHTTP para se comunicar com o servidor ao invés de Java Applet.

O processo é bastante simples: um determinado controle, do lado do cliente (browser), efetua um pedido, de forma assíncrona, a uma função do servidor através de uma função Javascript que é automaticamente embutida (esta é chamada de WebForm_DoCallback) na página pelo runtime do ASP.NET, e esta por sua vez é responsável por criar e configurar a estrutura necessária para enviar o pedido para o servidor. Depois que a função (embutida pelo ASP.NET) é executada, resta saber como invocar o método Javascript quando a resposta do servidor for retornada (callback). Eis o momento que entra em cena a Interface ICallbackEventHandler.

Esta Interface contém somente dois métodos: RaiseCallbackEvent(string) e GetCallbackResult(). Durante o processo de callback o ciclo de vida da página é um pouco diferente da normalidade, onde todos os eventos serão executados normalmente até o evento PreRender; como esse evento é responsável pela geração do código HTML da página, ele deve ser suprimido. Ao invés de retornar o HTML gerado pelo evento PreRender, é devolvido apenas o retorno do processamento do método GetCallbackResult(). O método RaiseCallbackEvent é invocado anteriormente, depois da conclusão do evento LoadComplete, onde podemos fazer inicializações de objetos, entre outras coisas necessárias para atender à este pedido. O porque de termos dois métodos nesta Interface é justamente para permitir o processamento assíncrono do pedido. Para termos uma idéia do fluxo de processamento de uma página com callback e sem callback, basta analisar a imagem abaixo:

Figura 1 - Fluxo de páginas com e sem callbacks.

Para vermos o funcionamento em um ambiente "quase real", devemos recuperar o nome da pessoa dado um número de C.P.F., ele irá fazer uma pesquisa e, se encontrar alguma pessoa com este código, o nome da mesma será retornado. Claro que isso não reflete exatamente o mundo real, já que nestes casos o ideal seria fazer uma consulta em alguma base de dados. O código abaixo mostra a implementação da Interface ICallbackEventHandler no CodeBehind de uma página ASPX.

public partial class Cadastro : System.Web.UI.Page, ICallbackEventHandler
{
    private string _cpf;
    
    public void RaiseCallbackEvent(string eventArgs)
    {
        this._cpf = eventArgs;
    }

    public string GetCallbackResult()
    {
        if(this._cpf.Length != 11)
            throw new ArgumentException("Comprimento do CPF incorreto.");

        if(this._cpf == "00011122233")
            return "Israel Aece";
        else if(this._cpf == "00011122244")
            return "Juliano Aece";
        else if(this._cpf == "00011122255")
            return "Claudia Fernanda";

        throw new ArgumentException("Registro inexistente.");
    }
}

Como podemos ver no código acima, o CodeBehind da nossa página já está preparado para trabalhar com o processo de callback. Mas somente isso não é necessário: devemos lembrar que o cliente (browser) é responsável por disparar o processo e, quando a função de callback retornar, também deverá receber o resultado, manipulá-lo e, conseqüentemente, apresentar ao usuário. A função que é responsável por disparar o ínicio do processo é chamada de WebForm_DoCallback, pois, como já vimos anteriormente, ela é embutida automaticamente pelo ASP.NET e a única coisa que temos que nos preocupar é quem (controle) e quando (evento) vai disparar esse processo.

Antes de apresentar o código responsável pela geração da função que será colocada no cliente para disparar o callback, é importante conhecer duas novas propriedades introduzidas no ASP.NET 2.0, para manipularmos os callbakcs. A primeira delas, a propriedade SupportsCallback, que está contida dentro de Request.Browser, que retorna um valor verdadeiro ou falso indicando se o browser do cliente suporta ou não os callbacks. Já a segunda é a propriedade IsCallback, que foi adicionada na classe Page que, assim como a propriedade IsPostBack, retorna um valor verdadeiro ou falso indicando se é ou não uma requisição resultante de um processo de callback.

Agora precisamos saber como atribuir a função WebForm_DoCallback em algum evento de um determinado controle no CodeBehind. A classe Page, através de uma nova propriedade chamada ClientScript, fornece um objeto do tipo ClientScriptManager, que este por sua vez, disponibiliza ao desenvolvedor um método chamado GetCallbackEventReference. Este método, dados seus parâmetros (os quais veremos a seguir), retorna uma String que refere-se à uma função client-side que será disparada através de algum evento (também no cliente), que dará início ao processo de callback. Para ilustrar o cenário que descrevemos acima, teremos o seguinte formulário:

Figura 2 - Formulário para os testes de callback.

Como prometido, vamos analisar detalhadamente a função GetCallbackEventReference. A assinatura do mesmo é a seguinte:

public string GetCallbackEventReference (
	string target,
	string argument,
	string clientCallback,
	string context,
	string clientErrorCallback,
	bool useAsync
)

O primeiro parâmetro, target, é o nome do controle de servidor que tratará o callback e o mesmo deve implementar a Interface ICallbackEventHandler. O segundo parâmetro, argument, é um argumento passado do lado cliente para o método do servidor RaiseCallbackEvent, proveniente da Interface ICallbackEventHandler. O terceiro parâmetro, clientCallback, é o nome da função cliente (Javascript) que será disparada quando o callback for processado e retornado para o cliente. Este método tem a responsabilidade de tratar e exibir o resultado. O parâmetro context é um valor que definimos e não é enviado ao servidor, mas é um valor que é passado a todos os métodos cliente. Como algum erro no processamento pode acontecer e uma Exception pode ser lançada, definimos através do parâmetro clientErrorCallback uma função que está também no cliente, que será responsável por tratar algum eventual erro. Finalmente o último dos parâmetros: useAsync; definimos como True se quisermos executar o processo de forma assíncrona e False se quisermos executá-lo de forma síncrona. Agora que já sabemos quais são as funções de cada um dos parâmetros, vejamos como fica o evento Load do WebForm:

protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsCallback && Request.Browser.SupportsCallback)
    {
        string funcaoJS = this.ClientScript.GetCallbackEventReference(
            this,
            "document.getElementById('" + this.txtCPF.ClientID + "').value",
            "ExibeNome",
            "'Aqui é o contexto.'",
            "TrataErro",
            true);

        this.btnBuscar.OnClientClick = string.Concat(funcaoJS, "; return false;");
    }
}

Com isso, só falta agora no cliente definirmos a função que tratará o retorno do callback e a função que será disparada caso algum Exception ocorrer. O código cliente fica semelhante ao que vemos abaixo:

<script language="javascript">
    function ExibeNome(arg, context)
    {
        document.getElementById('txtNome').value = arg;
    }
    
    function TrataErro(arg, context)
    {
        alert(arg);
        alert('Contexto: ' + context);
    }
</script>

Como podemos ver na figura 3, logo abaixo, o método WebForm_DoCallback foi atribuído no evento onClick do Button, já configurado com os devidos parâmetros que definimos no codebehind através do método GetCallbackEventReference. Para quem não percebeu como o método apareceu no evento onClick do Button, o retorno da função GetCallbackEventReference é atribuído à propriedade OnClientClick do Button que será responsável por iniciar o callback, ou melhor, será responsável por buscar o nome dado um C.P.F..

Figura 3 - Código definido no cliente.

Depois de todas essas configurações realizadas, podemos agora executar algum código no servidor sem a necessidade de atualizar a página. A responsável pela atualização dos dados retornados do callback é uma função Javascript que estará no cliente. É importante dizer que o controle GridView também fornece as funcionalidades de ordenação e paginação dos registros, sem a necessidade de atualizar a página toda. É muito simples colocar em funcionamento essa técnica, bastando apenas marcar a propriedade EnableSortingAndPagingCallbacks como True e a paginação e ordenação do controle GridView passa a ser feita sem a atualização da página como um todo.

CONCLUSÃO: Como pudemos ver no decorrer deste artigo, a Microsoft facilitou o desenvolvimento para trabalhar com o processamento no servidor sem a necessidade de atualizarmos/reconstruirmos a página toda, evitando que se recorra a componentes de terceiros para essa necessidade. Mas vale lembrar que a escrita de código Javascript ainda é necessária, já que depois que o callback é retornado, há necessidade de atualizar partes da página para exibir o resultado ao cliente. Para finalizar, é importante ratificar que a Microsoft está trabalhando em um projeto, chamado Atlas, que permitirá e deixará a codificação mais flexível para esse tipo de utilização.

Tags:

ASP.NET

Encriptando o Viewstate

by Israel Aece 3. January 2006 09:28

Matts Gibbs mostra neste artigo, uma nova funcionalidade do ASP.NET 2.0 para encriptar o viewstate da página. Isso pode ser configurado individualmente para cada página através do atributo ViewStateEncryptionMode ou para todas as páginas da aplicação, definindo isso no arquivo Web.Config.

Tags:

ASP.NET | Security

Visual Studio 2005 Web Application Project Preview

by Israel Aece 17. December 2005 13:29

Já está online a versão preview do Visual Studio 2005 Web Application Project, qual o ScottG postou em seu blog recentemente.

Para quem não leu, trata-se de uma forma de compilação e desenvolvimento de aplicações Web - ASP.NET, onde o principal objetivo é ter um impacto bem menor do que temos atualmente com a nova forma de compilação do ASP.NET 2.0, onde será trazido de volta  a forma com que fazemos no VS.NET 2002/2003.

Para quem se interessou, aqui está o link do site do projeto que foi criado pelo ScottG: http://webproject.scottgu.com, e tem ali todas as informações necessários para a instalação e criação dos projetos.

Tags: ,

ASP.NET

SqlDataSource - Uma propriedade interessante

by Israel Aece 8. December 2005 13:30

Estava eu dando manutenção em uma página de uma aplicação construída em ASP.NET 2.0, onde em um relatório que, dado uma consulta utilizando o controle SqlDataSource e seus devidos parametros, é executado uma Stored Procedure dentro de uma base de dados SQL Server e, o result-set é atribuído à um controle DataList no WebForm.

Até então tudo sem problemas e, o pior (para muitos, "o melhor"), sem nenhuma linha de código de servidor (VB.NET ou C#) escrita no CodeBehind. O problema começou quando defini para True a propriedade ConvertEmptyStringToNull de alguns parametros que, capturam os valores de controles do WebForm (como TextBox) para realizar a consulta. Estando essa propriedade definida como True, os parametros que não tiverem seus valores informados, serão convertidos em NULL e, consequentemente, enviados para a query ou Stored Procedure ser executada.

A partir daí as coisas deixaram de funcionar. Fiquei procurando, achando que tinha algo errado no próprio DataList e, mesmo através do Profiler do SQL Server, via que a Stored Procedure não era executada. Depois de algum tempo analisando as propriedades do controle SqlDataSource, vi que existe uma propriedade chamada CancelSelectOnNullParameter que, por padrão é definida como True e, como o próprio nome diz, se existir algum parametro nulo, a query/Stored Procedure não é executada.

Tags:

ASP.NET | Data

Powered by BlogEngine.NET 1.5.0.0
Theme by Mads Kristensen

Sobre

Meu nome é Israel Aece e sou especialista em tecnologias de desenvolvimento Microsoft, atuando como desenvolvedor de aplicações para o mercado financeiro utilizando a plataforma .NET. [ Mais ]

Twitter

Indicações

Introdução ao ASP.NET Web API - e-Book