I have problem to redirect to other page, for example, while i am keeping Credential Cache. I'm using:
cCache.Add(new Uri("http://mypage.com"), "Basic", new NetworkCredential("admin", "admin"));
and with:
using (var client = new HttpClient(new HttpClientHandler { Credentials = cCache }))
{
var request = new System.Net.Http.HttpRequestMessage()
{
RequestUri = new Uri("http://mypage.com"),
Method = HttpMethod.Get,
};
var result = new HttpResponseMessage();
var requestTask = client.SendAsync(request).ContinueWith((argRequestTask) =>
{
result = argRequestTask.Result;
});
requestTask.Wait();
}
status code that i get is 200 OK, and that is good. Result that i get is content of that page and that is good to, but im still on same page. If i redirect with:
Response.Redirect("http://mypage.com");
i lose my credentials. How i can solve this? tnx
Related
I want to have a Non Browser Client talk to an Application Load Balancer and send authenticated requests on behalf of a user in a Cognito pool. While my proof of concept is currently working, the Non Browser Client (a C# program) is manually constructing HTTP requests as though it is a browser and it just doesn't seem to be the right way of doing it.
Is there some way to do this via the SDK or some proper API I can consume?
I have included diagrams and my proof of concept code to illustrate my scenario.
If this is in fact the correct way of going about it, I'll just refactor and move forward.
[High Level
Sequence Diagram
/// <summary>
/// Proof of Concept Code.
/// </summary>
/// <returns></returns>
public static async Task ManualAuthAppLb2()
{
using (var handler = new HttpClientHandler
{
ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator,
AllowAutoRedirect = false
})
using (var client = new HttpClient(handler))
{
//--------------------------------------------------------//
//Go to /secure_page and get redirected //
var url = new Uri("https://<app_lb_id>.elb.amazonaws.com/secure_page");
var req = new HttpRequestMessage
{
Method = HttpMethod.Get,
RequestUri = url
};
var response = await client.SendAsync(req);
//--------------------------------------------------------//
//--------------------------------------------------------//
//Follow First Redirect to cognito /authorize page
var headers = response.Headers;
var rediruri = headers.First(h => h.Key.ToLower() == "location").Value.First();
req = new HttpRequestMessage
{
Method = HttpMethod.Get,
RequestUri = new Uri(rediruri)
};
response = await client.SendAsync(req);
//--------------------------------------------------------//
//--------------------------------------------------------//
//Follow next redirect to cognito /login page
headers = response.Headers;
var cookies = headers.First(h => h.Key.ToLower() == "set-cookie").Value.ToList();
var csrfToken = cookies.First().Split('=')[1]
.Split(';')[0]; ;
rediruri = headers.First(h => h.Key.ToLower() == "location").Value.First();
req = new HttpRequestMessage
{
Method = HttpMethod.Get,
RequestUri = new Uri(rediruri)
};
response = await client.SendAsync(req);
//--------------------------------------------------------//
//--------------------------------------------------------//
//Post Login Data to cognito
headers = response.Headers;
var data = new Dictionary<string, string>()
{
["_csrf"] = csrfToken,
["username"] = "someuser",
["password"] = "somepassword"
};
req = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = new Uri(rediruri),
Content = new FormUrlEncodedContent(data)
};
response = await client.SendAsync(req);
//--------------------------------------------------------//
//--------------------------------------------------------//
//Follow Redirect Back to Application Load Balancer
headers = response.Headers;
rediruri = headers.First(h => h.Key.ToLower() == "location").Value.First();
req = new HttpRequestMessage
{
Method = HttpMethod.Get,
RequestUri = new Uri(rediruri)
};
response = await client.SendAsync(req);
headers = response.Headers;
rediruri = headers.First(h => h.Key.ToLower() == "location").Value.First();
//--------------------------------------------------------//
//--------------------------------------------------------//
//Follow redirect back to /secure_page
req = new HttpRequestMessage
{
Method = HttpMethod.Get,
RequestUri = new Uri(rediruri)
};
response = await client.SendAsync(req);
headers = response.Headers;
Console.WriteLine(await response.Content.ReadAsStringAsync());
//--------------------------------------------------------//
}
}
There is an amazon SDK for C# : the image shows the packages used to develop such application.
I'm experiencing an intermittent problem with our SharePoint 2010 REST API. I have a .Net Core Console application that makes a series of calls to SharePoint List Endpoints to get a JSON response. My problem is that at random times, the API response is an error page:
A relative URI cannot be created because the 'uriString' parameter
represents an absolute URI.http://www.example.com/somefolder/file.svc
Is there a problem with my HTTPClient configuration? Is there a configuration setting that I can toggle in SharePoint to prevent the error or more reliable?
var uri = new Uri("http://www.example.com/");
var credential = new NetworkCredential("username", "password", "domain");
var credentialsCache = new CredentialCache { { uri, "NTLM", credential } };
var handler = new HttpClientHandler { Credentials = credentialsCache };
HttpClient Client = new HttpClient(handler);
Client.BaseAddress = new Uri("http://www.example.com/sharepoint/path/ListData.svc/");
// Make the list request
var result = await Client.GetAsync("MySharePointList");
To get the list items, the REST API URI like below.
http://sp2010/_vti_bin/ListData.svc/listname
Modify the code as below.
var siteUrl = "http://www.example.com/";
var listName = "MySharePointList";
var uri = new Uri(siteUrl);
var credential = new NetworkCredential("username", "password", "domain");
var credentialsCache = new CredentialCache { { uri, "NTLM", credential } };
var handler = new HttpClientHandler { Credentials = credentialsCache };
HttpClient client = new HttpClient(handler);
client.BaseAddress = new Uri(uri, "/_vti_bin/ListData.svc");
client.DefaultRequestHeaders.Add("Accept", "application/json;odata=verbose");
client.DefaultRequestHeaders.Add("ContentType", "application/json;odata=verbose");
var requestURL = siteUrl + "/_vti_bin/ListData.svc/" + listName;
// Make the list request
var result = client.GetAsync(requestURL).Result;
var items= result.Content.ReadAsStringAsync();
I'm trying to call the Shopware REST API from c#. Shopware has documentation for calling the API using curl, and mostly I can convert this to c# and HttpClient, but for some options I just don't know what headers to set:
The Shop is behind a basic htaccess-auth and has the Shopware auth using an apikey. My code so far:
var handler = new System.Net.Http.HttpClientHandler { Credentials = new NetworkCredential(htaccessUsername, htaccessPassword) });
var client = new System.Net.Http.HttpClient(handler);
using (var requestMessage = new HttpRequestMessage(HttpMethod.Get, apiUrl + "orders?limit=20"))
{
var encodedStr = Convert.ToBase64String(Encoding.Default.GetBytes($"{username}:{apiKey}"));
var authorizationKey = "Basic" + " " + encodedStr;
requestMessage.Headers.Add("Authorization", authorizationKey);
// curl_setopt($this->cURL, CURLOPT_RETURNTRANSFER, true);
// curl_setopt($this->cURL, CURLOPT_FOLLOWLOCATION, false);
// curl_setopt($this->cURL, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
// curl_setopt(
// $this->cURL,
// CURLOPT_HTTPHEADER,
// ['Content-Type: application/json; charset=utf-8']
// );
using (var responseMessage = await client.SendAsync(requestMessage))
{
var data = await responseMessage.Content.ReadAsStringAsync();
System.Diagnostics.Trace.WriteLine(data);
}
}
Basic htaccess auth is working, but the Shopware auth does fail with the following response in data:
"{\"success\":false,\"message\":\"Invalid or missing auth\"}"
I guess I Need to somehow achieve curl_setopt($this->cURL, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST); in c#, but I found no clue how to convert These curl options to a header.
Any help?
Looks like the answer for you is here:
var credCache = new CredentialCache();
var basicCred = new NetworkCredential(htaccessUsername, htaccessPassword);
var digestCred = new NetworkCredential(username, apiKey);
credCache.Add(new Uri("http://.com/"), "Basic", basicCred);
credCache.Add(new Uri("http://.com/"), "Digest", digestCred);
var httpClient = new HttpClient(new HttpClientHandler { Credentials = credCache });
I have a WebForms application which expose some WebAPI methods. The application uses standard Forms Authentication. I'm able to call methods from browser when I properly authenticated.
Now I want to call the API from c# application using HttpClient, but always receiving error 403 "Forbidden".
I can see that cookies container contains SessionId cookie.
The code:
var cookieContainer = new CookieContainer();
// authenticate
{
var webRequestHandler = new WebRequestHandler();
webRequestHandler.CookieContainer = cookieContainer;
webRequestHandler.UseCookies = true;
var client = new HttpClient(webRequestHandler);
client.BaseAddress = new Uri("https://localhost/<WEBFORMSAPP>/");
string unid = "<USERNAME$FIELD$NAME>";
string pwdid = "<PASSWORD$FIELD$NAME>";
HttpContent loginData = new FormUrlEncodedContent(
new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>(unid, "<USERNAME>"),
new KeyValuePair<string, string>(pwdid, "<PASSWORD>"),
}
);
System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
var postResult = client.PostAsync("<LOGINPAGE.aspx>", loginData);
postResult.Wait();
postResult.Result.EnsureSuccessStatusCode();
}
// call web api
{
var webRequestHandler = new WebRequestHandler();
webRequestHandler.CookieContainer = cookieContainer;
webRequestHandler.UseCookies = true;
var client = new HttpClient(webRequestHandler);
client.BaseAddress = new Uri("https://localhost/<WEBFORMSAPP>/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
var r = client.GetAsync("api/<SOME_METHOD>");
r.Wait();
r.Result.EnsureSuccessStatusCode(); // Fails with 403 error
}
To build the proper web request we need to provide server with the correct __VIEWSTATE value and the name of the button which cause the postback (in addition to the login/password pair).
To do this first we need to make a GET request to the login page and extract then __VIEWSTATE value.
I have used code from this blog post:
http://odetocode.com/articles/162.aspx
The code to create authorization cookies:
public CookieContainer CreateAuthorizationCookies(string login, string password)
{
var result = new CookieContainer();
System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
var webRequestHandler = new WebRequestHandler();
webRequestHandler.CookieContainer = result;
webRequestHandler.UseCookies = true;
var client = new HttpClient(webRequestHandler);
client.BaseAddress = new Uri("https://*********/");
// get viewstate
string viewstate;
{
var r = client.GetStringAsync("***/LoginPage.aspx");
r.Wait();
// see http://odetocode.com/articles/162.aspx
viewstate = ExtractViewState(r.Result);
}
HttpContent loginData = new FormUrlEncodedContent(
new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("__VIEWSTATE", viewstate),
new KeyValuePair<string, string>("***$UserName", login),
new KeyValuePair<string, string>("***$Password", password),
new KeyValuePair<string, string>("***$LoginButton", "Log In"), // "value" of the HTML input element
}
);
var postResult = client.PostAsync("****/LoginPage.aspx", loginData);
postResult.Wait();
postResult.Result.EnsureSuccessStatusCode();
return result;
}
After that we can use created CookieContainer in the further requests.
I'm working with one of user controlled application. This app is connecting with PHP files to login and do any other processes that requested.
in PHP I'm using session for detect if user already login. When they login successfully php sets and send login token id successfully.
I already working with IOS for same project and in IOS login process is working fine. IOS uses cookies automatically but I couldn't use cookies for windows app. Session has named cookie token id and php file checks token id with posted. I stuck in windows but I have no problem with IOS.
In windows store and phone app I can post perfectly and I can get respond message too. I can login perfectly as well. But when I navigate to second page of app it checks we are login or not again. When it check I'm facing with not logged in message. In my IOS app run perfectly. But in windows session token id check fails..
this is my php file that checks session token id in second page:
$tokencheck = $_POST['Tokenid'];
if($_SESSION["token"] == $tokencheck){
first page is login page and when login successfull windows phone gets token id and saves it successfully. After login, in a second page saved token id posting to php that I shared. I checked token id and thats true.
I do some research and I found problem is cookies. I can't use cookies right now. I did some more codes but still I stuck and couldn't solved this problem.
Codes sends post perfectly and also gets respond messages perfectly but I couldn't check session token id, this is because login check fails.
First page, first attempt with httpClient
var values = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("Email", txtEmail.Text),
new KeyValuePair<string, string>("Password", txtPassword.Password)
};
string url = ".../login.php";
CookieContainer Cookiejar = new CookieContainer();
var handler = new HttpClientHandler
{
CookieContainer = Cookiejar,
UseCookies = true//,
// UseDefaultCredentials = false
};
var httpClient = new HttpClient(handler);
httpClient.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/x-www-form-urlencoded"));
HttpResponseMessage response = await httpClient.PostAsync(url, new FormUrlEncodedContent(values));
response.EnsureSuccessStatusCode();
var responseString = await response.Content.ReadAsStringAsync();
var wwwUri = new Uri(url);
Cookiejar.SetCookies(wwwUri, Cookiejar.GetCookieHeader(wwwUri));
First page second attempt with HttpWebRequest
CookieContainer cookies = new CookieContainer();
HttpWebRequest getRequest = (HttpWebRequest)WebRequest.Create(url);
getRequest.CookieContainer = cookies;
getRequest.Method = "POST";
HttpWebResponse response = (HttpWebResponse)await getRequest.GetResponseAsync();
var sr = new StreamReader(response.GetResponseStream() );
string responseString = sr.ReadToEnd();
I also tried some other codes that I found in internet but can't solved yet.
Second page is also :
object lgntoken = Windows.Storage.ApplicationData.Current.LocalSettings.Values["logintokenid"];
var values = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("Tokenid", Convert.ToString(lgntoken))
};
string url = ".../get_projects_list.php";
CookieContainer Cookiejar = new CookieContainer();
var wwwUri = new Uri(url);
// Cookiejar.SetCookies(wwwUri, Cookiejar.GetCookieHeader(wwwUri));
Cookiejar.GetCookieHeader(wwwUri);
var handler = new HttpClientHandler
{
CookieContainer = Cookiejar,
UseCookies = true
};
System.Diagnostics.Debug.WriteLine("Login Token: " + Convert.ToString(lgntoken) + "..");
var httpClient = new HttpClient(handler);
HttpResponseMessage response = await httpClient.PostAsync(url, new FormUrlEncodedContent(values));
response.EnsureSuccessStatusCode();
var responseString = await response.Content.ReadAsStringAsync();
System.Diagnostics.Debug.WriteLine("Project List Data : " + responseString + " ++ Login Token: " + Convert.ToString(lgntoken) + "..");
I have some experiance in IOS but I'm newbie in windows store apps. I stuck about this issue and already not understood what should I do, how can I set or get cookies in a first and second page. Waiting your helps, thank you.
SOLVED !
problem is cookies resets in second page. And also need define cookies..
using cookies with httpclient :
public static CookieContainer cookies = new CookieContainer();
var handler = new HttpClientHandler
{
CookieContainer = cookies,
UseCookies = true,
UseDefaultCredentials = false
};
HttpClient htclient = new HttpClient(handler);
Full code example
First page login screen :
public static CookieContainer cookies = new CookieContainer();
private async void btnLogin_Click(object sender, RoutedEventArgs e)
{
...
var values = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("Email", txtEmail.Text),
new KeyValuePair<string, string>("Password", txtPassword.Password)
};
string url = ".../login.php";
var handler = new HttpClientHandler
{
CookieContainer = cookies,
UseCookies = true,
UseDefaultCredentials = false
};
HttpClient htclient = new HttpClient(handler);
htclient.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/x-www-form-urlencoded"));
HttpResponseMessage response = await htclient.PostAsync(url, new FormUrlEncodedContent(values));
response.EnsureSuccessStatusCode();
var responseString = await response.Content.ReadAsStringAsync();
Second page should use first page cookies.. After login :
var values = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("Tokenid", Convert.ToString(lgntoken))
};
string url = ".../get_projects_list.php";
var handler = new HttpClientHandler
{
CookieContainer = MainPage.cookies,
UseDefaultCredentials = true,
UseCookies = true
};
System.Diagnostics.Debug.WriteLine("Login Token: " + Convert.ToString(lgntoken) + "..");
// var httpClient = new HttpClient(handler);
HttpClient htclient = new HttpClient(handler);
htclient.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/x-www-form-urlencoded"));
HttpResponseMessage response = await htclient.PostAsync(url, new FormUrlEncodedContent(values));
response.EnsureSuccessStatusCode();
var responseString = await response.Content.ReadAsStringAsync();
System.Diagnostics.Debug.WriteLine("Project List Data : " + responseString +
" ++ Login Token: " + Convert.ToString(lgntoken) + "..");
...
}