Olá, pessoal,
depois de ter o privilégio de mais um ano de vida quero mostrar como usar o impersonate via web no seu aplicativo ou
no da empresa. Mas antes veja com atenção sobre o contexto que estou abordando
e desenvolvendo o software.
Referências:
- Linguagem C#.NET
- Ferramenta: Visual
Studio .NET 2008 - Framework 3.5
- Plataforma:
ASP.NET
Contexto 1
Tenho um servidor que está na internet,
ou seja, tem ip fixo, tem sites instalados, tem IIS instalado e configurado.
Tenho outro servidor que serve para uso interno, isto é, não está na internet,
mas está na mesma rede. Só tem IP interno e não tem externo e, para entrar
nele, preciso apenas de um usuário com permissão de acesso a determinada pasta.
Contexto 2
A aplicação que tenho hoje gera um pdf
com assinatura digital e joga o mesmo no servidor interno, ou seja, não tenho
acesso via web para acessar estes arquivos, no caso de querer visualizá-los
pela internet, browser ou outra ferramenta.
Contexto 3
Devido aos contextos 1 e 2, preciso usar
um usuário que tenha acesso à determinada pasta onde estão os arquivos. Lembrando
que estes artigos estão em um servidor interno e a minha aplicação web está em
um servidor na internet, na mesma rede.
Para ter este tipo de acesso, preciso
de um usuário da rede com permissão à pasta e assim conseguir mostrar os
arquivos pelo sistema web acessando com usuário local. Para acessar com o
usuário da rede é necessário fazer um impersonate.
Para quem não sabe, é usar um usuário específico para acessar determinado local
em vez de usar o usuário da web.
Depois de toda essa explicação, quero
mostrar passo a passo como fazer o impersonate
no sistema web com objetivo de acessar um determinado local com usuário
específico. Geralmente usamos isso em empresas.
Código
O primeiro passo é importar algumas
classes do framework .net. No meu caso estou usando a versão 3.5:
using System.Security;<br /><br />using System.Security.Principal;<br /><br />using System.Runtime;<br /><br />using System.Runtime.InteropServices;<br /><br />using System.Web;<br /><br />using System.Web.Security;O segundo passo é usar algumas dll’s do
sistema operacional Windows para fazer este logon. Criei algumas constantes de
usuário, senha e domínio:
#region " Impersonate " <br /><br /> [System.Runtime.InteropServices.DllImport("advapi32.dll")]<br /> public static extern int LogonUser(String lpszUserName,<br /> String lpszDomain,<br /> String lpszPassword,<br /> int dwLogonType,<br /> int dwLogonProvider,<br /> ref IntPtr phToken); <br /><br /> [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]<br /> public static extern int DuplicateToken(IntPtr hToken,<br /> int impersonationLevel,<br /> ref IntPtr hNewToken);<br /><br /> [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]<br /> public static extern bool RevertToSelf();<br /><br /> [DllImport("kernel32.dll", CharSet = CharSet.Auto)]<br /> public static extern bool CloseHandle(IntPtr handle);<br /><br /> const int LOGON32_PROVIDER_DEFAULT = 0;<br /> const int LOGON32_LOGON_INTERACTIVE = 2;<br /><br /> static WindowsImpersonationContext wic;<br /> const string User = "seu_usuario";<br /> const string Domain = "seu_dominio";<br /> const string Pwd = "sua_senha";<br /><br /> #endregionO terceiro passo é criar um método que
loga utilizando as credenciais do usuário local, ou seja, aquele que coloquei
nas constantes. O método precisa passar alguns parâmetros de entrada. Resolvi
criar um método estático para não precisar criar um “new” ou uma nova
instância:
static public bool ImpersonateValidUser(String userName, String domain, String password)<br /> {<br /> WindowsIdentity wi;<br /> IntPtr token = IntPtr.Zero;<br /> IntPtr tokenDuplicate = IntPtr.Zero; <br /><br /> if (RevertToSelf())<br /> {<br /> if (LogonUser(userName, domain, password, LOGON32_LOGON_INTERACTIVE,<br /> LOGON32_PROVIDER_DEFAULT, ref token) != 0)<br /> {<br /> if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)<br /> {<br /> wi = new WindowsIdentity(tokenDuplicate);<br /> wic = wi.Impersonate();<br /> if (wic != null)<br /> {<br /> CloseHandle(token);<br /> CloseHandle(tokenDuplicate);<br /> return true;<br /> }<br /> }<br /> }<br /> }<br /> if (token != IntPtr.Zero)<br /> CloseHandle(token);<br /> if (tokenDuplicate != IntPtr.Zero)<br /> CloseHandle(tokenDuplicate);<br /> return false;<br /> }O quarto e último passo: usei o
Load_Page da página criada para fazer tudo que criamos anteriormente com poucas
linhas de código. Chamei o método (code 3) e usei a variável falando para usar
o usuário local e abrir o arquivo:
if (ImpersonateValidUser(User, Domain, Pwd))<br /> {<br /> using (wic)<br /> {<br /> }<br /> } Note que usei as constantes de usuário,
domínio e senha, depois coloquei “using (wic)” que constitui da variável do
usuário logado localmente. Dentro do using (wic) coloquei o código que chama o
arquivo pdf dinamicamente e dessa forma o arquivo é mostrado sem qualquer
problema, veja na próxima imagem.
Tudo que for escrito dentro do using
(wic) será feito com o usuário do impersonate.

Bom,
eu fico por aqui e espero que tenha entendido tudo sobre o artigo. Não
expliquei o que fiz dentro do método para não prolongar muito o texto. O
objetivo foi ser “objetivo”.
Qualquer dúvida
pode entrar em contato pelo site.








