Veremos nesse artigo como utilizar de forma correta e segura as variáveis de sistema do servidor através do ASP.NET (Visual C#), obtendo informações por parte dos clientes, conexões, servidor e etc. Para isso utilizaremos uma classe nativa do .NET, ServerVariables, que por sua vez, herda algumas informações da HttpRequest. Todos nós sabemos que um dos servidores de publicações mais utilizados para desenvolvimento de aplicações Web usando ASP.NET é o IIS (Internet Information Service) e muitas das vezes é necessário obter determinadas informações que estão contidas apenas neste servidor de aplicação.

Um exemplo bem simples é quando obtemos informações do pool de configuração de um determinado aplicativo. Mas, quem nunca se deparou com a necessidade de obter informações do cliente que está acessando o seu sistema ou aplicativo? Ou até mesmo obter informações da conexão atual do sistema? Pois é, algumas informações ficam nas variáveis de servidor (ServerVariables) e neste artigo veremos como conseguir acesso a tais informações de forma rápida e segura.

É possível obter informações de cabeçalhos HTTP que, por questões de segurança, não é recomendado obter. Mas caso o seu domínio esteja com o uso de certificados, não há motivos para preocupação, pois seus dados de cabeçalho não poderão ser alterados. Caso não use certificado, ai existe um ponto a ser questionado se vale a pena ou não o uso de ServerVariables, pois estes dados podem ser alterados por usuários mal-intencionados. Provavelmente, as variáveis de HTTPS não poderão ser testadas ou utilizadas em um ambiente que não seja seguro. Caso utilize um certificado em seu domínio, não precisa se preocupar com relação à segurança, pois o certificado já é responsável por isso.

Estas variáveis são sempre criadas quando uma nova página ASP.NET é requisitada no servidor. Ou seja, assim que é requisitada, essas variáveis são automaticamente atualizadas.

Essas variáveis podem ser obtidas de várias maneiras, dentre elas podemos citar:

  • Em ASP utilizando o Request.ServerVariables (Coleção);
  • Em COM + Componentes para ASP use o método IRequest::get_ServerVariables;
  • Em ASP.NET utilizando o Request.ServerVariables[“CHAVE”].
  • Em aplicativos ISAPI, use o GetServerVariable como função de retorno.

Além dessas citadas acima, existem outras formas e outras linguagens que podem obter essas tais informações.

Mas quando utilizar as ServerVariables? Veja as seguintes situações:

  • Capturar nome do usuário logado no servidor;
  • Capturar IP do usuário logado;
  • Capturar parâmetros de uma requisição;
  • Capturar número da porta da qual requisição foi enviado;
  • Capturar a página que referenciou a requisição;
  • Capturar dados do certificado do cliente;
  • Contador de usuários visitantes;
  • Contador de usuários online;
  • Capturar dados do cabeçalho HTTP;
  • Capturar Geolocalização do Cliente.

Para que possamos utilizar as ServerVariables é necessário utilizar a propriedade HttpRequest.ServerVariables, que está disponível desde o .NET Framework 2.0.

Para os exemplos abaixo vamos utilizar a versão 4.5 do framework. Além disso, precisamos do IIS 7.0 ou superior com funções ASP.NET habilitado, além do Rewrite Module URL 2.0 instalado.

Na Listagem 1 temos o código que será responsável por efetuar a listagem de todas essas variáveis de servidor existente com seus respectivos valores retornados. Para que o código funcione corretamente, a sua página deverá estar importando a classe System.Collections.Specialized, pois é através dela que podemos usar alguns métodos e propriedades já predefinidos para as variáveis de servidor.

O objetivo de utilizar esta classe é que nela existem coleções especializadas com fins muitos específicos como, por exemplo, a NameValueCollection, que aceita vários valores por chave.

Listagem 1. Código para carregar variáveis de servidor

  protected void CarregarVariaveisServidor()
  {
    // Declaração de variáveis auxiliares.
     int loop1, loop2;
     NameValueCollection valorColecao;
     // Carregandos ServerVariable da coleção.
     valorColecao = Request.ServerVariables;
     // Obtem os nomes de todas as chaves da coleção e guarda em um array.
     String[] colecao = valorColecao.AllKeys;
    // Varrendo todas as variáveis existentes no servidor.
     for (loop1 = 0; loop1 < colecao.Length; loop1++)
     {
       // Escrevendo na tela as variáveis existentes no servidor.
        Response.Write("Chave da variavel: " + colecao[loop1] + "<br>");
        String[] valor = valorColecao.GetValues(colecao[loop1]);
       // Varrendo todas as propriedades da variavel.
        for (loop2 = 0; loop2 < valor.Length; loop2++)
        {
         // Escrevendo na tela todos os valores das variáveis encontradas.
          Response.Write("Valor da Variavel: " + loop2 + ": " + Server.HtmlEncode(valor[loop2]) + "<br>");
         }
     }
  }

Perceba que esta classe é estática, pois não foi necessário criar uma instância de um objeto da mesma para poder utilizar os métodos e propriedades contidas nela. Basta executar a chamada dos métodos para obter os seus respectivos retornos.

A seguir descreveremos algumas das variáveis de servidor que são comumente utilizadas:

  • REQUEST_METHOD – Retorna o tipo de requisição efetuada pelo usuário em uma determinada requisição. Exemplo: GET ou POST;
  • SERVER_NAME– Retorna o nome do servidor referente à URL acessada em uma determinada requisição;
  • APPL_PHYSICAL_PATH – Retorna o caminho físico completo do projeto;
  • QUERY_STRING– Contêm os parâmetros passados através de uma requisição de uma URL qualquer esses parâmetros podem ser de GET ou POST. Tudo depois de um ‘?’;
  • AUTH_TYPE- Método de autenticação que o servidor usa para validar usuários quando eles tentam acessar um script protegido.
  • PATH_INFO– Armazena e retorna a informação do caminho da URL requisitada pelo navegador. (Se oAllowPathInfoForScriptMappings estiver definido com verdadeiro, o caminho retornado será apenas o nome da aplicação.zip);
  • CERT_SERVER_SUBJECT– Retorna o campo Subject do certificado SSL do servidor com base na requisição solicitada;
  • CERT_SUBJECT - Retorna o campo Subject do certificado SSL do cliente com base na requisição solicitada;
  • LOGON_USER- Retorna os dados da conta Windows NT do usuário logado;
  • CONTENT_LENGHT– permite determinar a extensão do conteúdo da solicitação HTTP do cliente usando o método POST.
  • HTTP_UA_COLOR– retorna o número de cores disponíveis na máquina do usuário.
  • CERT_KEYSIZE – Retorna o número de bits requeridos para a chave SSL;
  • HTTP_ACCEPT – Retorna o valor do cabeçalho que contém uma lista de formatos aceitos, por exemplo, gif, bitmap, etc.
  • HTTP_CONNECTION – Retorna uma string com o tipo de conexão aceita;
  • HTTP_UA_PIXELS –Contém a resolução da tela do navegador que fez a requisição.
  • REMOTE _ADRR –Retorna o endereço IP do host remoto que esta solicitando o serviço.
  • HTTP_VERSION – Retorna o nome e a versão do protocolo utilizado na requisição;
  • REMOTE _HOST –Retorna o nome do host que esta fazendo a solicitação do serviço.
  • HTTP_UA_OS– Retorna o nome e a versão do software servidor que está respondendo ao pedido.
  • HTTP_COOKIE – Retorna uma string cookie que foi incluído como pedido na requisição;
  • LOGON_USER– Retorna a conta no Windows NT do usuário.
  • SERVER_PORT– Retorna o número da porta da qual a requisição foi enviada para o servidor;
  • SERVER_PROTOCOL– Retorna o nome e a versão para o protocolo de informação.
  • SERVER_SOFTWARE– Retorna o nome e a versão do software do servidor.
  • SCRIPT_MAP– Retorna e informa a base da URL
  • SCRIPT_NAME– Retorna e informa todo o caminho virtual para o roteiro presente.
  • REQUEST_ADDR– Retorna e informa o endereço IP do host remoto que fez a requisição.
  • ALL_HTTP – Retorna todos os cabeçalhos enviados pelo cliente;
  • ALL_RAW – Recupera todos os cabeçalhos de forma bruta;
  • APP_POOL_ID – Retorna o nome do pool de aplicativos que está sendo executado no processo do IIS (Esta opção só está disponível caso sejam implementadas em um servidor IIS superior a versão 5.1);
  • APPL_MD_PATH – Recupera o caminho da metabase do aplicativo;
  • CACHE_URL – para uso somente em aplicações de ISAPI. Retorna o nome inequívoco para a URL atual. (Esta opção só está disponível caso sejam implementadas em um servidor IIS superior a versão 5.1);
  • CERT_FLAGS – Retorna informações se o certificado de cliente está presente;
  • SCRIPT_NAME – Retorna um caminho virtual para o script ser executado;
  • GATEWAY_INTERFACE – Retorna a revisão da especificação CGI usada pelo servidor;
  • CERT_COOKIE – Retorna a identificação única para o certificado do cliente;
  • SERVER_PORT_SECURE – Retorna uma sequência de caracteres que contém 0 ou 1. Se o pedido está sendo tratado na porta segura, então o valor é 1, senão ele é 0;
  • URL – Retorna a base da url requisitada;
  • CERT_ISSUER – Retorna o campo Emissor do certificado do cliente (O = MS, OU = IAS, CN name = usuário, C = EUA);
  • AUTH_PASSWORD - O valor inserido no diálogo de autenticação do cliente.Esta variável está disponível apenas se a autenticação básica é usada;
  • CERT_SERIALNUMBER – Retorna o campo de número de série do certificado cliente;
  • HTTP_<NomeCabeçalho> - Retorna o valor armazenado no cabeçalho.O servidor interpreta quaisquer caracteres de sublinhado ( _ ) como, por exemplo, HTTP_CABECALHO_DO_THIAGO, procurando assim por um cabeçalho como o nome CABECALHO_DO_THIAGO;
  • HTTP_ACCEPT_ENCODING – Retorna uma lista de tipos de codificações aceitas;
  • HTTP_ACCEPT_LANGUAGE – Retorna uma string descrevendo o idioma a ser usado para exibir o conteúdo.
  • HTTP_USER_AGENT – Retorna uma string descrevendo o navegador que enviou a requisição solicitada;
  • PATH_TRANSLATED – Retorna o caminho físico que mapeia para o caminho virtual em PATH_INFO. Esta variável é usada pelo IIS durante o processo de aplicativos ISAPI.
  • SCRIPT_TRANSLATED – Retorna o caminho físico canônico para o script listado na variável SCRIPT_NAME. Mas atenção, pois esta opção só está disponível caso sejam implementadas em um servidor IIS superior a versão 5.1;
  • UNENCODED_URL – Retorna a URL codificada, por exemplo, /dir/index.aspx?querystring. Esta opção só está disponível caso sejam implementadas em um servidor IIS inferiores a versão 4.1;
  • UNMAPPED_REMOTE_USER – Retorna o nome do utilizador, uma vez que é derivado a partir do cabeçalho de autorização enviado pelo cliente. Antes de executar esta variável o nome do utilizador é mapeado para uma conta do Windows (REMOTE_USER). Caso você tenha um filtro de autenticação instalado no seu servidor Web para efetuar o mapeamento de usuários, utilize antes a variável LOGON_USER;
  • CACHE_URL – Para o uso apenas em aplicações ISAPI. Retorna o nome inequívoco para a URL atual. É necessário utilizar a versão UNICODE desta variável em conjunto com a função de invalidação de cache modo Kernel para expulsar as entradas colocadas no cache.

A variável de servidor "UNICODE_CACHE_URL" é utilizada em conjunto com a função de invalidação de cache recuperada pela função o HSE_REQ_GET_CACHE_INVALIDATION_CALLBACK.Esta invalida respostas em cache em HTTP.SYS se essas respostas são produzidos por pedidos, ou por ISAPIs chamandoHSE_REQ_VECTOR_SEND.

Uma forma mais simples de obter os valores dessas variáveis de servidores é através da sua chave, ou seja, de acordo com a Listagem 1 os nomes em negrito são as suas respectivas chaves, basta utilizar a sintaxe informada logo no início do artigo. Na Listagem 2 temos o uso dessas variáveis passando como parâmetro apenas o valor da chave.

A sintaxe para obter variável através da chave é:

Request.ServerVariables[“CHAVE”];

Listagem 2. Obtendo Variáveis do Server a partir da chave

  private void ObterVariavelServerPelaChave()
          {
              // Carregando valor da variável de servidor        
  // Obtém o valor do servidor origem. (Nome do servidor de origem)
              string servidorOrigem = Request.ServerVariables["SERVER_NAME"];
  // Obtém o valor do navegador utilizado. (Nome do navegador)
              string navegadorUtilizado = Request.ServerVariables["HTTP_USER_AGENT"];
              // Número de cores disponíveis na máquina do cliente.
              string numeroCores = Request.ServerVariables["HTTP_UA_COLOR"];
              // Escrevendo na tela os valores obtidos a partir das variáveis de Servidor.
              Response.Write("SERVIDOR ORIGEM: " + servidorOrigem + "<br>");
              Response.Write("NAVEGADOR UTILIZADO: " + navegadorUtilizado + "<br>");
              Response.Write("NÚMERO DE CORES DISPONÍVEL MÁQUINA USUÁRIO: " + numeroCores + "<br>");
  }

Na Listagem 3 temos um código que pode ser utilizado para efetuar tradução dos textos do teu site por exemplo. Nele iremos capturar como obter a linguagem do Servidor em que o browser irá interpretar e mostrar para o usuário o conteúdo da página.

Listagem 3. Obtendo o idioma que o browser deverá mostrar o seu conteúdo.

  public string getTextoTraduzido(){
    // Obtendo o idioma para mostrar o conteúdo no browse
    string linguagem = Request.ServerVariables["HTTP_ACCEPT_LANGUAGE"];
   // Testando qual idioma
   if (linguagem == "pt-BR")
      // Retornando o texto em português caso a linguagem seja a pt_BR
      return "Olá desenvolvedores. Estamos utilizando as variaveis de servidor.";
   else if (linguagem == "ENG")
      // Retornando o texto em Inglês caso a linguagem seja a ENG
      return "Hello developers. We are using the server variables.";
 // Retornando texto para outros idiomas
   return "Idioma não detectado.";
  }

Na Listagem 4 temos um código muito simples da tela de erro genérica utilizada em diversos sistemas que tem um botão “Voltar” que, após o usuário clicar nele, retorna para a página anterior. Acreditem, aquele botão usa a ServerVariable para capturar a página que fez a referência para a requisição anterior.

Listagem 4. Obtendo Página anterior através das ServerVariables

  protected void PaginaAnterior(){
    // Obtendo o valor da página anterior através da variável de servidor
    string urlAnterior = Request.ServerVariables["HTTP_REFERER"];
    // Direcionando para a página obtida  
    Server.TransferRequest(urlAnterior);
    //ou
    //Response.Redirect(urlAnterior);
  }

Na Listagem 5 iremos demonstrar uma função que utilizando as variáveis de servidor para retornar o IP do cliente independente da sua conexão estar utilizando proxy ou não. Essa função é de simples entendimento e podemos ver que a variável HTTP_X_FORWARDED_FOR é utilizada para quando o usuário tiver em uma conexão utilizando Proxy, enquanto a variável REMOTE_ADDR é utilizada para clientes que estão em uma conexão sem Proxy.

Após fazer o build e rodar este código, teremos o retorno do IP da sua máquina.

Listagem 5. Recuperando IP do Cliente com proxy e sem proxy

  protected string recuperarIP(){
    // Conexão utilizando proxy
    string ipUser = string.Empty;
    if (Request.ServerVariables["HTTP_X_FORWARDED_FOR"] == null)
    {
       // Conexão sem utilizar proxy
       ipUser = System.Web.HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
    }
    // Retornando o IP capturado que estava guardado na variável de servidor
    return ipUser;
  }

Caso esteja testando o código da Listagem 5 de forma local, o resultado da variável REMOTE_ADDR será o IP 127.0.0.1. Para descobrir seu IP externo acesse o link http://meuip.net.br/ e faça a validação dos valores retornados pelo site, junto ao que o código retornou.

A seguir temos algumas dicas importantes:

  1. Antes de utilizar as ServerVariables certifique-se de estar utilizando um certificado SSL em seu domínio para que seus dados de cabeçalhos HTTP não sejam facilmente alterados. Sem este certificado é praticamente impossível utilizar as variáveis de servidor.
  2. Se caso utilizarmos segurança de acesso anônimo não será possível utilizar as ServerVariables, pois as variáveis não serão preenchidas. Essas configurações podem ser feitas no webConfig na sua seção “<autorização>”.
  3. Outra ideia muito legal de se utilizar é gravar os dados de variáveis locais em uma sessão através da Global.asax do projeto. Dessa forma, você terá as informações registradas e não necessitará ficar invocando métodos da classe.
  4. Algumas vezes você poderá se deparar com o seguinte erro: HTTP 417 Expectation failed (Falha de expectativa). Essa falha se dá quando tentamos fazer uma requisição por WebRequest tentando obter determinado valor de uma certa variável. Para sanar esse problema utilize o seguinte código antes de realizar o processo de captura de informações:
    System.Net.ServicePointManager.Expect100Continue = false;
  5. Por padrão, as regras de reescrita para variáveis de servidor não podem ser alteradas, porém, antes de utilizá-las, verifique se o seu servidor IIS está configurado desta forma para evitar problemas futuros. Quaisquer dúvidas consulte o material da própria Microsoft (vide seção Links).

Espero que tenham gostado do assunto!

Links

Variáveis de servidor
https://msdn.microsoft.com/pt-br/library/ms524602.aspx

Configuração do IIS
http://social.technet.microsoft.com/wiki/contents/articles/5222.guia-de-sobrevivencia-internet-information-services-iis-pt-br.aspx

Tipos de autenticação IIS
http://social.technet.microsoft.com/wiki/contents/articles/tipos-de-autentica-231-227-o-no-iis-7-7-5-pt-br.aspx

Configuração de aplicativos ISAPI
http://wiki.rh3software.com/doku.php?id=instalacao_configuracao:portal:configuracao_iis_isapi_dll

Reescrita de variáveis
https://technet.microsoft.com/pt-br/library/cc754617%28v=ws.10%29.aspx
https://technet.microsoft.com/pt-br/library/ee791883(v=ws.10).aspx

Escrevendo aplicativos do IIS mais seguros
https://msdn.microsoft.com/pt-br/library/ms525871.aspx?f=255&MSPPError=-2147217396