HttpWebRequest usando autenticação básica

138

Estou tentando passar por uma solicitação de autenticação que imita a "solicitação básica de autenticação" que estamos acostumados a ver ao configurar o IIS para esse comportamento.

O URL é: https://telematicoprova.agenziadogane.it/TelematicoServiziDiUtilitaWeb/ServiziDiUtilitaAutServlet?UC=22&SC=1&ST=2
(aviso: https!)

Este servidor está em execução no UNIX e Java como servidor de aplicativos.

Este é o código que eu uso para conectar-me a este servidor:

CookieContainer myContainer = new CookieContainer();
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://telematicoprova.agenziadogane.it/TelematicoServiziDiUtilitaWeb/ServiziDiUtilitaAutServlet?UC=22&SC=1&ST=2");
request.Credentials = new NetworkCredential(xxx,xxx);
request.CookieContainer = myContainer;
request.PreAuthenticate = true;
HttpWebResponse response = (HttpWebResponse)request.GetResponse();

(Copiei isso de outro post neste site). Mas eu recebo esta resposta do servidor:

A conexão subjacente foi fechada: ocorreu um erro inesperado em um envio.

Acho que tentei todas as tarefas possíveis que meu conhecimento em c # me oferece, mas nada ...

Kenny Rullo
fonte
Eu acho que este teria funcionado se você tivesse adicionado: request.UseDefaultCredentials = false;
bpeikes

Respostas:

274

Você também pode adicionar o cabeçalho da autorização.

Basta criar o nome "Autorização" e o valor "Básico BASE64 ({USERNAME: PASSWORD})"

String username = "abc";
String password = "123";
String encoded = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(username + ":" + password));
httpWebRequest.Headers.Add("Authorization", "Basic " + encoded);

Editar

A codificação foi alterada de UTF-8 para ISO 8859-1 por Qual codificação devo usar para autenticação básica HTTP? e o comentário de Jeroen.

Zambonilli
fonte
3
Então, como você tem certeza de que UTF8 é a codificação correta para usar?
Jeroen Wiert Pluimers
2
Boa pegada. Parece que o cabeçalho de autenticação da solicitação deve ser codificado na ISO-8859-1. Por stackoverflow.com/questions/7242316/…
Zambonilli
1
Aaaargh! 1: Obrigado, companheiro. 2. Eu realmente gostaria de entender por que os outros métodos, configurando o método de autenticação no CredentialCache, não funcionariam. Eles deveriam, não são?
mshthn
1
Toda a documentação do msdn aponta para sim, os outros métodos devem funcionar. No entanto, nunca consegui fazê-los funcionar.
Zambonilli
Não estou trabalhando para mim (nem utf-8 nem ISO-8859-1). Alguma sugestão o que verificar? Funciona quando eu faço "webRequest.Credentials = new NetworkCredential (UserID, Password);" .
precisa
56

Eu finalmente entendi!

string url = @"https://telematicoprova.agenziadogane.it/TelematicoServiziDiUtilitaWeb/ServiziDiUtilitaAutServlet?UC=22&SC=1&ST=2";
WebRequest request = WebRequest.Create(url);
request.Credentials = GetCredential();
request.PreAuthenticate = true;

e isso é GetCredential()

private CredentialCache GetCredential()
{
    string url = @"https://telematicoprova.agenziadogane.it/TelematicoServiziDiUtilitaWeb/ServiziDiUtilitaAutServlet?UC=22&SC=1&ST=2";
    ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;
    CredentialCache credentialCache = new CredentialCache();
    credentialCache.Add(new System.Uri(url), "Basic", new NetworkCredential(ConfigurationManager.AppSettings["ead_username"], ConfigurationManager.AppSettings["ead_password"]));
    return credentialCache;
}

YAY!

Kenny Rullo
fonte
29

Se você pode usar a WebClientclasse, o uso da autenticação básica se torna simples:

var client = new WebClient {Credentials = new NetworkCredential("user_name", "password")};
var response = client.DownloadString("https://telematicoprova.agenziadogane.it/TelematicoServiziDiUtilitaWeb/ServiziDiUtilitaAutServlet?UC=22&SC=1&ST=2");
Tamir
fonte
8

Tente o seguinte:

System.Net.CredentialCache credentialCache = new System.Net.CredentialCache(); 
credentialCache.Add(
    new System.Uri("http://www.yoururl.com/"),
    "Basic", 
    new System.Net.NetworkCredential("username", "password")
);

...
...

httpWebRequest.Credentials = credentialCache; 
MrEyes
fonte
É uma autenticação definitivamente básica? Além disso, você pode acessar o recurso com seu nome de usuário / senha por meio de um navegador?
MrEyes
Parece ser uma autenticação básica por https. Se você clicar no link que eu forneci, o navegador exibirá a solicitação de nome de usuário / senha ", da mesma forma que quando você faz" autenticação básica "no IIS ou usando um arquivo .htaccss em uma pasta via apache. Tentei usar o violinista, mas Eu não tenho idéia sobre #
Kenny Rullo
Acabei de saber que o site está sendo executado no servidor http da IBM. Esta pode ser uma notícia útil?
Kenny Rullo
5

Para aqueles que usam RestSharp , pode falhar ao usar o SimpleAuthenticator (possivelmente devido ao não uso da ISO-8859-1 nos bastidores). Consegui fazê-lo enviando explicitamente cabeçalhos de autenticação básica:

string username = "...";
string password = "...";

public IRestResponse GetResponse(string url, Method method = Method.GET)
{
    string encoded = Convert.ToBase64String(Encoding.GetEncoding("ISO-8859-1").GetBytes($"{username}:{password}"));
    var client = new RestClient(url);
    var request = new RestRequest(method );
    request.AddHeader("Authorization", $"Basic {encoded}");
    IRestResponse response = client.Execute(request);
    return response;
}

var response = GetResponse(url);
txtResult.Text = response.Content;
Alexei
fonte
3

O código a seguir resolverá a resposta json se houver autenticação básica e proxy implementados. O IIS 7.5 Hosting Problm também será resolvido.

public string HttpGetByWebRequ(string uri, string username, string password)
{
//For Basic Authentication
    string authInfo = username + ":" + password;
    authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo));

//For Proxy
    WebProxy proxy = new WebProxy("http://10.127.0.1:8080", true);

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
    request.Method = "GET";
    request.Accept = "application/json; charset=utf-8";
    request.Proxy = proxy;

    request.Headers["Authorization"] = "Basic " + authInfo;

    var response = (HttpWebResponse)request.GetResponse();

    string strResponse = "";
    using (var sr = new StreamReader(response.GetResponseStream()))
    {
        strResponse= sr.ReadToEnd();

    }

    return strResponse;
}
Mahabubuzzaman
fonte
Não está funcionando para mim (nem utf-8 nem ISO-8859-1 nem padrão). Alguma sugestão do que verificar? Observe - funciona quando eu faço "webRequest.Credentials = new NetworkCredential (UserID, Password);"
precisa
1

A construção a seguir não estava funcionando corretamente para mim:

request.Credentials = new NetworkCredential("user", "pass");

Eu usei CredentialCache:

CredentialCache credentialCache = new CredentialCache
{
    {
        new Uri($"http://{request.Host}/"), "Basic",
        new NetworkCredential("user", "pass")
    }
};
request.Credentials = credentialCache;

No entanto, se você desejar adicionar várias credenciais de autenticação básica (por exemplo, se houver um redirecionamento de que você saiba), poderá usar a seguinte função que eu criei:

private void SetNetworkCredential(Uri uriPrefix, string authType, NetworkCredential credential)
{
    if (request.Credentials == null)
    {
        request.Credentials = new CredentialCache();
    }

    if (request.Credentials.GetCredential(uriPrefix, authType) == null)
    {
        (request.Credentials as CredentialCache).Add(uriPrefix, authType, credential);
    }
}

Espero que ajude alguém no futuro.

Gucu112
fonte
0

Primeira coisa, para mim ServicePointManager.SecurityProtocol = SecurityProtocolType. Tls12 funcionou em vez de Ssl3.

Em segundo lugar, tive que enviar a solicitação de autenticação básica, juntamente com alguns dados (codificado por formulário). Aqui está a amostra completa que funcionou perfeitamente para mim, depois de tentar muitas soluções.

Isenção de responsabilidade: O código abaixo é uma mistura de soluções encontradas neste link e em alguns outros links de stackoverflow, obrigado pelas informações úteis.

        ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
        String username = "user_name";
        String password = "password";
        String encoded = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(username + ":" + password));

        //Form Data
        var formData = "var1=val1&var2=val2";
        var encodedFormData = Encoding.ASCII.GetBytes(formData);

        HttpWebRequest request = (HttpWebRequest)WebRequest.Create("THE_URL");
        request.ContentType = "application/x-www-form-urlencoded";
        request.Method = "POST";
        request.ContentLength = encodedFormData.Length;
        request.Headers.Add("Authorization", "Basic " + encoded);
        request.PreAuthenticate = true;

        using (var stream = request.GetRequestStream())
        {
            stream.Write(encodedFormData, 0, encodedFormData.Length);
        }

        HttpWebResponse response = (HttpWebResponse)request.GetResponse();
        var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
Jiten
fonte