Dev (Back & Front)ARTIGO

Usando SOAP Headers – Segurança em WebService

Olá, gostaria de explicar como criar WebService com segurança com um passo a passo. Muitos usuários usam essa nova tecnologia de forma errada e sem qualquer fundamento. No decorrer do artigo, você irá entender o que estou falando.

Requerido:
Visual Studio.NET 2008
FrameWork: 3.5
Linguagem: C#.NET
Tecnologia: WebService

Geralmente um desenvolvedor de software, arquiteto ou analista de sistema coloca a segurança do WebService mais no servidor e no banco de dados; não está errado e até aconselho fazer isso. Você deve estar me perguntando, mas como eu coloco uma segurança no sistema?

Existem alguns profissionais de WebService que não sabem como fazer a segurança de forma correta e colocam o usuário e senha como parâmetro de entrada no método.

Trabalhei em uma empresa que tinha tudo, o servidor tinha segurança SSL para acessar, tinha segurança na senha criptografada no banco de dados, mas passava o usuário e senha como parâmetro de entrada no método, por exemplo: AbrirChamado(string usuário, string senha, string parâmetros).

Dessa forma, não adianta ser seguro no servidor, seguro no banco de dados, se a senha e o usuário estão sendo passados na chamada do método. Principalmente se esses dados foram passados sem qualquer criptografia.

Estou certo que esse tipo de tecnologia é novo no mercado brasileiro, só que não existe justificativa para falta de segurança e para aprender mais sobre o assunto. Em um livro que escrevi em 2002 ensinei a criar e trabalhar com WebService.

Seguem abaixo os próximos passos na criação de um WebService seguro. Lembrando que é um exemplo bem simples, mas que serve como base para customização. O primeiro é um HelloWorld mesmo. (Code 1.1)

using System;<br />using System.Web;<br />using System.Web.Services;<br />using System.Web.Services.Protocols;<br /><br /><br />[WebService(Namespace = "http://tempuri.org/")]<br />[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]<br /><br /><br />public class Service : System.Web.Services.WebService<br />{<br />    public ValidationSoapHeader Authentication;<br />    private const string DEV_TOKEN = "12345";<br />    public Service()<br />    {<br />        //Uncomment the following line if using designed components<br />        //InitializeComponent();<br />    }<br /><br /><br />    [SoapHeader("Authentication")]<br />    [WebMethod]<br /><br />    public string HelloWorld()<br />    {<br />        if (Authentication != null && Authentication.DevToken == DEV_TOKEN)<br />        {<br />            return "Hello World";<br />        }<br />        else<br />        {<br />            throw new Exception("Authentication Failed");<br />        }<br />    }<br />}

Code 1.1

Explicação:

A primeira coisa foi colocar o public ValidationSoapHeader Authentication e uma constante chamada DEV_TOKEN (private const string DEV_TOKEN = “12345”;) que serve como um “token” para ser autenticado e enviado no cabeçalho do WebService. Isso também evita do usuário comum ver o dado na assinatura do método. Logo depois, criei em cima do método HelloWorld uma tag chamada [SoapHeader(“Authentication”)] antes da tag de [WebMethod].

Dentro do método, verifiquei se o Authentication é igual a null e o Authentication.DevToken é igual a constante criada do token anterior, ou seja, DEV_TOKEN. Se houver essa validação, ele continua o método sem qualquer problema. O passo seguinte foi criar uma outra classe para colocar o cabeçalho de validação do soap header. (Code 1.2)

using System;<br />using System.Data;<br />using System.Configuration;<br />using System.Web;<br />using System.Web.Security;<br />using System.Web.UI;<br />using System.Web.UI.WebControls;<br />using System.Web.UI.WebControls.WebParts;<br />using System.Web.UI.HtmlControls;<br />using System.Web.Services.Protocols;<br /><br />/// <summary><br />/// Summary description for ePhoneCredentials<br />/// </summary><br />public class ValidationSoapHeader : SoapHeader<br />{<br />    private string _devToken;<br />    public ValidationSoapHeader()<br />    {<br />    }<br />    public ValidationSoapHeader(string devToken)<br />    {<br />        this._devToken = devToken;<br />    }<br />    public string DevToken<br />    {<br />        get { return this._devToken; }<br />        set { this._devToken = value; }<br />    }<br />}

Code 1.2

Explicação: 

Como falado anteriormente, criei uma outra classe chamada ValidationSoapHeader que extende de SoapHeader. Coloquei seus atributos colocando get e set.  Note que existe um construtor da classe que recebe como parâmetro o token atribuído manualmente.

O próximo passo é mostrar como consumir o WebService pelo cliente, passando os dados corretos dentro do SoapHeader.

Lembro também que pode ser colocado qualquer outro tipo de atributo no SoapHeader e verificado dentro do código. Pode ser gerada uma chave mais precisa e criptografada para a verificação também. Esse exemplo dado até o momento serve apenas como base.

localhost.ValidationSoapHeader header = new ConsoleMyCsharpClient.localhost.ValidationSoapHeader();<br />header.DevToken = "12345";<br />localhost.Service ws = new ConsoleMyCsharpClient.localhost.Service();<br />ws.ValidationSoapHeaderValue = header;<br />Console.WriteLine(ws.HelloWorld());<br />Console.ReadLine(); 

Code 1.3

Explicação:

Criei uma instância do validador, coloquei o número do token e chamei o serviço passando o SoapHeader antes de chamar o método. Caso o método tiver qualquer parâmetro de entrada, basta colocá-lo na chamada normalmente.

Bom, fico por aqui e espero ter ajudado.

Qualquer dúvida, favor entrar em contato.

Com mais de 20 anos trabalhando no mercado de tecnologia. Mestre em Engenharia Elétrica voltada para o mundo mobile, com mais de 20 livros publicados e cerca de 700 artigos publicados com intuito de ajudar àqueles que querem aprender a programar (site, software, desktop, serviços, api e mobile). Site pessoal: https://www.mauriciojunior.net - MVP, MCAD, MCP Microsoft

Ver perfil