Suponha uma aplicação que consome serviços WCF REST, e que por algum motivo, precisa passar como chave characteres especiais, por exemplo:
Serviço - http://servico.com/Produtos/{key1}/{key2}
Vamos chamar o serviço da seguinte maneira: http://servico.com/Produtos/Livro/SN#908762
Repare que o número de série do livro sendo pedido contém o character especial '#' .
Usamos o código abaixo para consumir o serviço:
public void BuscarProduto()
{
var factory = Services.Factory.Produtos();
factory.Get(p.Tipo, p.ID);
}
public static class Factory
{
private static string GetUri(string serviceKey)
{
return System.Configuration.ConfigurationManager.AppSettings[serviceKey];
}
public static IProdutos Produtos()
{
string uri = GetUri("RESTServiceProdutos");
var factory = new WebChannelFactory<WcfRestServicesLayer.Administrativo.Usuarios.IProdutos>(new Uri(uri));
return factory.CreateChannel();
}
}
Se algum dos charcteres %,&,*,:,<,>,+,#, /, ?,\ estiver contido na chave no momento em que o método factory.Get for executado, o ASP.NET retorna um erro 400 Bad Request ou 404 Not Found
Existem vários motivos para isso acontcer, mas o motivo principal é a politica de segurança do asp.net. O asp.net está na verdade se defendendo de possíveis tentativas de injeção de código e ataques ao seu serviço.
Permitir estes characteres nas chaves é possível sim, mas não é recomendado pois deixaria o seu serviço vulnerável.
Para permitir os characteres especiais temos os passos abaixo:
Para permitir os chars %,&,*,:,<, e > insira no arquivo web.config:
<httpRuntime requestPathInvalidCharacters="" requestValidationMode="2.0"/>
<pages validateRequest="false"/>
Para permitir o char + adicione
<system.webServer>
<security>
<requestFiltering allowDoubleEscaping="true" />
</security>
</system.webServer>
Para liberar o char #, ?, / e \ é necessário escrever alguma espécie de Parser (conversor)
e adicioná-lo ao construtor do seu serviço e depois modificar o web.config
Abaixo segue um exemplo de parser escrito pelo Peter Tian (http://social.msdn.microsoft.com/profile/peter%20qian%20-%20msft/?ws=usercard-hover)
Ele própio não recomenda a utilizção deste código, é apenas uma prova de conceito e pode danificar seus servidores de produção.
public Produtos()
{
string uri = HttpContext.Current.Request.Url.OriginalString;
StringBuilder replaceUri = new StringBuilder();
bool inquote = false;
for (int i = 0; i < uri.Length; ++i)
{
switch (uri[i])
{
case '\'':
replaceUri.Append(uri[i]);
inquote = !inquote;
break;
case '#':
case '\\':
case '/':
case '?':
if (inquote)
{
replaceUri.AppendFormat("%{0:X}", (int)uri[i]);
}
else
{
replaceUri.Append(uri[i]);
}
break;
default:
replaceUri.Append(uri[i]);
break;
}
}
}
<configSections>
<section name="uri" type="System.Configuration.UriSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
</configSections>
<uri>
<schemeSettings>
<add name="http" genericUriParserOptions="DontUnescapePathDotsAndSlashes"/>
<add name="https" genericUriParserOptions="DontUnescapePathDotsAndSlashes"/>
</schemeSettings>
</uri>
Antes de tentar aplicar os work-around mencionados acima, você deveria rever a arquitetura da sua aplicação. A recomendação é que não existam characteres especiais na URI, por medidas de segurança.
No comments:
Post a Comment