I have been trying to use the .NET AWS Cloudfront API to create signed cookies for my S3 bucket, but whenever I send an HTTP request with the cookies that are created, I just get a result of "Forbidden". Is there something I am doing wrong in this code? Thanks.
CookiesForCannedPolicy cookies = AmazonCloudFrontCookieSigner.GetCookiesForCannedPolicy(
#"http://distribution123abc.cloudfront.net/*",
"KEYPAIRID",
new FileInfo(#"C:\bla\privatekey.pem"),
DateTime.Now.AddHours(1));
Uri target = new Uri(#"http://distribution123abc.cloudfront.net");
HttpWebRequest pleaseWork = (HttpWebRequest)WebRequest.Create(#"http://distribution123abc.cloudfront.net/files/test.txt");
if (pleaseWork.CookieContainer == null)
{
pleaseWork.CookieContainer = new CookieContainer();
}
pleaseWork.CookieContainer.Add(new Cookie(cookies.Signature.Key, cookies.Signature.Value) { Domain = target.Host } );
pleaseWork.CookieContainer.Add(new Cookie(cookies.KeyPairId.Key, cookies.KeyPairId.Value) { Domain = target.Host } );
pleaseWork.CookieContainer.Add(new Cookie(cookies.Expires.Key, cookies.Expires.Value) { Domain = target.Host } );
try
{
WebResponse response = pleaseWork.GetResponse();
Console.WriteLine("Response content length: " + response.ContentLength);
}
catch(WebException e)
{
Console.WriteLine(e.Message);
}
I found a solution. I had to change two things:
First I had to use signed cookies for a custom policy rather than a canned policy (and therefore use a "Policy" cookie rather than an "Expires" cookie).
Second, the domain I was setting for my cookies was incorrect. I needed to set the domain as just ".cloudfront.net", rather than specifying the domain for my distribution.
This is what my code looked like in the end:
CookiesForCustomPolicy cookies = AmazonCloudFrontCookieSigner.GetCookiesForCustomPolicy(
#"http://distribution123abc.cloudfront.net/*",
new StreamReader(#"C:\bla\privatekey.pem"),
"KEYPAIRID",
DateTime.Now.AddHours(1),
DateTime.Now.AddHours(-1),
"1.1.1.1");
string domain = ".cloudfront.net";
HttpWebRequest pleaseWork = (HttpWebRequest)WebRequest.Create(#"http://distribution123abc.cloudfront.net/files/test.txt");
if (pleaseWork.CookieContainer == null)
{
pleaseWork.CookieContainer = new CookieContainer();
}
pleaseWork.CookieContainer.Add(new Cookie(cookies.Signature.Key, cookies.Signature.Value) { Domain = domain } );
pleaseWork.CookieContainer.Add(new Cookie(cookies.KeyPairId.Key, cookies.KeyPairId.Value) { Domain = domain } );
pleaseWork.CookieContainer.Add(new Cookie(cookies.Policy.Key, cookies.Policy.Value) { Domain = domain } );
try
{
WebResponse response = pleaseWork.GetResponse();
Console.WriteLine("Response content length: " + response.ContentLength);
}
catch(WebException e)
{
Console.WriteLine(e.Message);
}
Related
.NET framework 4.6.1 website using OIDC authentication (Microsoft.Owin.Security.OpenIdConnect 4.1.0)
As part of the authentication I include "code_challenge". The following code is based on this example.
RedirectToIdentityProvider = n =>
{
//ProcessCertificateValidation();
if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.Authentication)
{
if (AppSettingsKey.AuthCodeChallangeEnabled.Enabled)
{
// generate code verifier and code challenge
var codeVerifier = CryptoRandom.CreateUniqueId(32);
string codeChallenge;
using (var sha256 = SHA256.Create())
{
var challengeBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(codeVerifier));
codeChallenge = Base64UrlEncoder.Encode(challengeBytes);
}
// set code_challenge parameter on authorization request
n.ProtocolMessage.Parameters.Add("code_challenge", codeChallenge);
n.ProtocolMessage.Parameters.Add("code_challenge_method", "S256");
// remember code verifier in cookie (adapted from OWIN nonce cookie)
RememberCodeVerifier(n, codeVerifier);
}
if (AppSettingsKey.MultiFactorAuthEnabled.Enabled)
n.ProtocolMessage.AcrValues = authCfg.AcrValues ?? n.ProtocolMessage.AcrValues;
}
logger.Debug("OIDC-Notification: RedirectToIdentityProvider Called");
//if signing out, add the id_token_hint
if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.Logout)
{
logger.Debug(" RequestType=" + OpenIdConnectRequestType.Logout);
var idTokenHint = n.OwinContext.Authentication.User.FindFirst("id_token");
if (idTokenHint != null)
{
logger.Debug(" IdTokenHint got from n.OwinContext.Authentication.User");
n.ProtocolMessage.IdTokenHint = idTokenHint.Value;
}
logger.Debug(" IdTokenHint=" + n?.ProtocolMessage?.IdTokenHint);
}
return Task.CompletedTask;
},
I confirmed that the "codeVerifierCookie" is sent.
AuthorizationCodeReceived = async n =>
{
logger.Debug("OIDC-Notification: AuthorizationCodeReceived Called");
logger.Debug(" Code=" + n.Code);
logger.Debug(" AuthenticationType=" + n.Options.AuthenticationType);
if (authCfg.DiscoverEndpoints)
{
var disco = await n.Options.ConfigurationManager.GetConfigurationAsync(n.OwinContext.Request.CallCancelled);
authCfg.TokenEndpoint = disco.TokenEndpoint;
authCfg.UserinfoEndpoint = disco.UserInfoEndpoint;
authCfg.EndsessionEndpoint = disco.EndSessionEndpoint;
//authCfg.RevocationEndpoint = disco.RevocationEndpoint;
authCfg.WebKeySetEndpoint = disco.JwksUri;
}
if (AppSettingsKey.AuthCodeChallangeEnabled.Enabled) {
var codeVerifier = RetrieveCodeVerifier(n);
// attach code_verifier
n.TokenEndpointRequest.SetParameter("code_verifier", codeVerifier);
}
var requestMessage = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Post, authCfg.TokenEndpoint);
requestMessage.Content = new System.Net.Http.FormUrlEncodedContent(n.TokenEndpointRequest.Parameters);
var responseMessage = await n.Options.Backchannel.SendAsync(requestMessage);
responseMessage.EnsureSuccessStatusCode();
var responseContent = await responseMessage.Content.ReadAsStringAsync();
Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectMessage message = new Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectMessage(responseContent);
logger.Debug(" IdToken=" + message.IdToken);
logger.Debug(" AccessToken=" + message.AccessToken);
n.HandleCodeRedemption(message);
},
The issue is that when trying to retrieve the "codeVerifierCookie" it does not exist, when trying to login in Edge or Chrome (on Firefox its there).
Here are the methods used to send, retrieve and get the code verification. CookieManager is configured to be Microsoft.Owin.Host.SystemWeb.SystemWebChunkingCookieManager().
private void RememberCodeVerifier(RedirectToIdentityProviderNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> n, string codeVerifier)
{
var properties = new AuthenticationProperties();
properties.Dictionary.Add("cv", codeVerifier);
n.Options.CookieManager.AppendResponseCookie(
n.OwinContext,
GetCodeVerifierKey(n.ProtocolMessage.State),
Convert.ToBase64String(Encoding.UTF8.GetBytes(n.Options.StateDataFormat.Protect(properties))),
new CookieOptions
{
SameSite = SameSiteMode.None,
HttpOnly = true,
Secure = n.Request.IsSecure,
Expires = DateTime.UtcNow + n.Options.ProtocolValidator.NonceLifetime
});
}
private string RetrieveCodeVerifier(AuthorizationCodeReceivedNotification n)
{
string key = GetCodeVerifierKey(n.ProtocolMessage.State);
string codeVerifierCookie = n.Options.CookieManager.GetRequestCookie(n.OwinContext, key);
if (codeVerifierCookie != null)
{
var cookieOptions = new CookieOptions
{
SameSite = SameSiteMode.None,
HttpOnly = true,
Secure = n.Request.IsSecure
};
n.Options.CookieManager.DeleteCookie(n.OwinContext, key, cookieOptions);
}
var cookieProperties = n.Options.StateDataFormat.Unprotect(Encoding.UTF8.GetString(Convert.FromBase64String(codeVerifierCookie)));
cookieProperties.Dictionary.TryGetValue("cv", out var codeVerifier);
return codeVerifier;
}
private string GetCodeVerifierKey(string state)
{
using (var hash = SHA256.Create())
{
return OpenIdConnectAuthenticationDefaults.CookiePrefix + "cv." + Convert.ToBase64String(hash.ComputeHash(Encoding.UTF8.GetBytes(state)));
}
}
Why does the "codeVerifierCookie" missing when I try to login from Edge or Chrome? Could it be some default setting or maybe my setup is missing something? Why does it work on Firefox?
Thank you for reading my post and I welcome every and any input on the issue.
Have you used HTTPS when testing your app? Cookies that assert SameSite=None must also be marked as Secure. I think the issue might be related with Same-Site cookies setting.
I find a thread which has the same issue as yours, you can refer to it. Besides, there's a detailed article about working with SameSite cookies in ASP.NET, you can also check it for more information.
I am a begginer and i work in a MVC project which I cant understand it well yet.
I can't understand where does the API takes data from when I try to connect in Login Screen.
It doesn't use Entity Framework and there isn't a json with the data.
When I enter Id and Pass it calls an API (GetAPIResponse) which somehow finds that is correct.
Need help to understand the code and the logic behind it.
LoginBL class contains:
public bool IsAuthenticated(LoginEntity user)
{
string url = string.Empty;
string callType = string.Empty;
string server = string.Empty;
try
{
// get URL, Call type, Server from config file
url = ConfigurationManager.AppSettings["login_url"].ToString();
callType = ConfigurationManager.AppSettings["calltype"].ToString();
server = ConfigurationManager.AppSettings["server"].ToString();
// Encrypt password
string password = Scrambler.GenerateMD5Hash(user.Password);
// Prepare content for the POST request
string content = #"calltype=" + callType + "&server=" + server + "&user=" + user.UserName + "&pass=" + password + "";
Debug.WriteLine("Callcenter login url: " + content);
HttpResponseMessage json_list = ApiCallBL.GetAPIResponse(url, content);
LoginResponseEntity obj = new LoginResponseEntity();
obj = JsonConvert.DeserializeObject<LoginResponseEntity>(json_list.Content.ReadAsStringAsync().Result);
Debug.WriteLine(callType + " Response: " + json_list.Content.ReadAsStringAsync().Result);
//if API resultCode return 0 then user details and token save in session for further use
if (obj.ResultCode == 0)
{
int restrict = obj.UserInfo.RestrictCallType.HasValue ?
obj.UserInfo.RestrictCallType.Value : 0;
HttpContext.Current.Session["user_id"] = obj.UserInfo.usr_id;
HttpContext.Current.Session["user_name"] = obj.UserInfo.usr_username;
HttpContext.Current.Session["user_group_id"] = obj.UserInfo.UserGroupID;
HttpContext.Current.Session["groupid"] = obj.UserInfo.groupid;
HttpContext.Current.Session["token"] = obj.Token;
HttpContext.Current.Session["web_server_url"] = obj.ServerInfo.web_server_url;
HttpContext.Current.Session["centerX"] = obj.ServerInfo.DefaultGeoX;
HttpContext.Current.Session["centerY"] = obj.ServerInfo.DefaultGeoY;
HttpContext.Current.Session["dateFormat"] = obj.ServerInfo.dateFormat;
HttpContext.Current.Session["currency"] = obj.ServerInfo.currency;
HttpContext.Current.Session["customer_img"] = obj.ServerInfo.customer_img;
HttpContext.Current.Session["groups"] = obj.groups;
HttpContext.Current.Session["restrict_call_type"] = restrict ;
Debug.WriteLine("obj.UserInfo.UserGroupID " + obj.UserInfo.UserGroupID);
Debug.WriteLine("obj.UserInfo.groups " + obj.groups);
//HttpContext.Current.Session["defaultLanguage"] = obj.ServerInfo.defaultLanguage;
HttpCookie cookie = new HttpCookie("Login");
// if remember me checked then user name and password stored in cookie else cookes is expired
if (user.RememberMe)
{
cookie.Values.Add("user_name", obj.UserInfo.usr_username);
cookie.Values.Add("pwd", user.Password);
cookie.Expires = DateTime.Now.AddDays(15);
HttpContext.Current.Response.Cookies.Add(cookie);
}
else
{
cookie.Expires = DateTime.Now.AddDays(-1);
HttpContext.Current.Response.Cookies.Add(cookie);
}
return true;
}
else
{
//ResultCode -5 :Invalid Login ,-1:Database Error ,-2:Server Error ,-3:Invalid Parameter specified ,-4:Invalid Token
return false;
}
}
catch
{
throw;
}
finally
{
url = string.Empty;
callType = string.Empty;
server = string.Empty;
}
}
Okay here after converts pass to MD5 creates a "string content" with the information given.
Then in next line (HttpResponseMessage json_list = ApiCallBL.GetAPIResponse(url, content);) calls the API with the url and content as parameters where it finds if the data exists.
API code:
public static HttpResponseMessage GetAPIResponse(string url, string content)
{
StringBuilder traceLog = null;
HttpContent httpContent = null;
try
{
traceLog = new StringBuilder();
traceLog.AppendLine("Start: BusinessLayer getAPIResponse() Request Data:- " + DateTime.Now + "URL = " + url + "&content = " + httpContent);
using (HttpClient client = new HttpClient())
{
httpContent = new StringContent(content);
httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
var resp = client.PostAsync(url, httpContent).Result;
Debug.WriteLine("resp: " + resp.Content.ReadAsStringAsync().Result);
traceLog.AppendLine("End: BusinessLayer getAPIResponse() call completed HttpResponseMessage received");
return resp;
}
}
catch
{
throw;
}
finally
{
traceLog = null;
httpContent.Dispose();
url = string.Empty;
content = string.Empty;
}
}
In the following line, console prints the result that I cant understand where it cames from (Debug.WriteLine("resp: " + resp.Content.ReadAsStringAsync().Result);)
Sorry for the confusion , I am in my first job with zero work experience and I am called to learn how this works alone without proper education on ASP.NET from them.
You will not go very far without debbugger. Learn how to debug in Visual Studio (YouTube tutorials might be fastest way). Place debug points along critical points in code (for example moment when client sends and receives response is line var resp = client.PostAsync...) and check variables.
Url for API server is actually defined in the line
url = ConfigurationManager.AppSettings["login_url"].ToString();
ConfigurationManager means Web.config file, check it's appSettings section for login_url entry, there is your url.
Btw, using (HttpClient client = new HttpClient()) is not a good way to use a HttpClient and will lead to port exhaustion. It's ok for small number of requests, but for larger ones you must reuse it, or use HttpClientFactory (for .NET Core).
I am having problems invoking the PayPal IPN. I dont know which URL to give or which URL i am meant to give. I have looked all over the internet for help but there does not seem to be anything available hence why i have come here.
So firstly, i have the PaymentWithPaypal Action
public ActionResult PaymentWithPaypal(int? id, Page page)
{
//getting the apiContext as earlier
APIContext apiContext = Models.Configuration.GetAPIContext();
try
{
string payerId = Request.Params["PayerID"];
if (string.IsNullOrEmpty(payerId))
{
string baseURI = Request.Url.Scheme + "://" + Request.Url.Authority + "/ControllerName/PaymentWithPayPal?";
var guid = Guid.NewGuid().ToString();
//CreatePayment function gives us the payment approval url
//on which payer is redirected for paypal acccount payment
var createdPayment = this.CreatePayment(apiContext, baseURI + "guid=" + guid);
//get links returned from paypal in response to Create function call
var links = createdPayment.links.GetEnumerator();
string paypalRedirectUrl = null;
while (links.MoveNext())
{
Links lnk = links.Current;
if (lnk.rel.ToLower().Trim().Equals("approval_url"))
{
//saving the payapalredirect URL to which user will be redirected for payment
paypalRedirectUrl = lnk.href;
}
}
// saving the paymentID in the key guid
Session.Add(guid, createdPayment.id);
return Redirect(paypalRedirectUrl);
}
else
{
// This section is executed when we have received all the payments parameters
// from the previous call to the function Create
// Executing a payment
var guid = Request.Params["guid"];
var executedPayment = ExecutePayment(apiContext, payerId, Session[guid] as string);
if (executedPayment.state.ToLower() != "approved")
{
return View("FailureView");
}
}
}
catch (Exception ex)
{
Logger.Log("Error" + ex.Message);
return View("FailureView");
}
return View("SuccessView");
}
This is the code for the IPN.
[HttpPost]
public HttpStatusCodeResult Receive()
{
//Store the IPN received from PayPal
LogRequest(Request);
//Fire and forget verification task
Task.Run(() => VerifyTask(Request));
//Reply back a 200 code
return new HttpStatusCodeResult(HttpStatusCode.OK);
}
private void VerifyTask(HttpRequestBase ipnRequest)
{
var verificationResponse = string.Empty;
try
{
var verificationRequest = (HttpWebRequest)WebRequest.Create("https://www.sandbox.paypal.com/cgi-bin/webscr");
//Set values for the verification request
verificationRequest.Method = "POST";
verificationRequest.ContentType = "application/x-www-form-urlencoded";
var param = Request.BinaryRead(ipnRequest.ContentLength);
var strRequest = Encoding.ASCII.GetString(param);
//Add cmd=_notify-validate to the payload
strRequest = "cmd=_notify-validate&" + strRequest;
verificationRequest.ContentLength = strRequest.Length;
//Attach payload to the verification request
var streamOut = new StreamWriter(verificationRequest.GetRequestStream(), Encoding.ASCII);
streamOut.Write(strRequest);
streamOut.Close();
//Send the request to PayPal and get the response
var streamIn = new StreamReader(verificationRequest.GetResponse().GetResponseStream());
verificationResponse = streamIn.ReadToEnd();
streamIn.Close();
}
catch (Exception exception)
{
Logger.Log("Error" + exception.Message);
//Capture exception for manual investigation
}
ProcessVerificationResponse(verificationResponse);
}
private void LogRequest(HttpRequestBase request)
{
// Persist the request values into a database or temporary data store
}
private void ProcessVerificationResponse(string verificationResponse)
{
if (verificationResponse.Equals("VERIFIED"))
{
Logger.Log("Verified");
// check that Payment_status=Completed
// check that Txn_id has not been previously processed
// check that Receiver_email is your Primary PayPal email
// check that Payment_amount/Payment_currency are correct
// process payment
}
else if (verificationResponse.Equals("INVALID"))
{
Logger.Log(verificationResponse);
}
else
{
//Log error
}
}
Now to clear things up. My understanding of the IPN is that when a customer purchases an item, the SELLER will get an email telling them that they have sold a product and then from this you can access transactionId etc.
So in my view i have a form with a button that looks like this.
#Html.ActionLink("Buy Now", "PaymentWithPaypal", new { Id = Model.Id, #class = "" })
This is what takes the customer to paypal where they can then purchase but this is where i am stuck because im not sure how to call the IPN or if it needs its own view.
ANY CLARITY WOULD BE OF MUCH HELP AT THIS MOMENT IN TIME.
One way is to put this under PayPal account settings. Once you click on your "App", below it you see the redirect url option. Just add it there. Paypal .net sdk doesn't have the option to pass notify_url. All other modes have. Because, paypal.net sdk accepts return_url which is usually the same action method as also mentioned in your code.
Check this:
https://developer.paypal.com/docs/classic/ipn/integration-guide/IPNSetup/#
In case you want to achieve real time events, you need to use webhooks now. Documentation below:
https://github.com/paypal/PayPal-NET-SDK/wiki/Webhook-Event-Validation
We are encountering a bit of an odd issue on our integration code with SharePoint.
We've managed to get the integration working using SAML tokens, see code below.
The problem is that sometimes it times out when getting the FedAuth cookie or making the request to SharePoint.
The timeouts might point to load or network issues but they are reproducible.
The first unit test on the unit test suite gets the cookie without any problem every single time, but it fails on the second.
To make this more mystifying, it seems to work fine whenever I have fiddler capturing traffic.
Even more annoying is the fact that if i run the second unit test and not the first, the test works fine.
It's as if SharePoint refuses to issue another cookie for the same client until a certain amount of time has passed, unless going through Fiddler.
I should add, that I have tried both storing the cookie for subsequent requests and getting it again for each request, it seems to make no difference.
Any help would be appreciated.
public static ClientContext CreateClientContext(SharePointClaimsConnection connection)
{
if (connection == null)
{
throw new ArgumentNullException("connection");
}
logger.DebugFormat("Create Client Context for connection: {0}", connection);
ClientContext context = new ClientContext(connection.WebUrl);
try
{
if (connection.SecurityTokenServiceEndPoint != null && !String.IsNullOrEmpty(connection.Realm))
{
CookieInfo token = GetToken(connection);
if (token == null)
{
lock (syncRoot)
{
token = GetToken(connection);
if (token == null)
{
token = GetFedAuthCookie(connection);
if (token != null)
{
tokens[connection] = token;
}
}
}
}
if (token != null)
{
context.ExecutingWebRequest += (s, e) =>
{
e.WebRequestExecutor.WebRequest.KeepAlive = true;
for (int i = 0; i < e.WebRequestExecutor.WebRequest.Headers.Count; i++)
{
string key = e.WebRequestExecutor.WebRequest.Headers.GetKey(i);
string value = e.WebRequestExecutor.WebRequest.Headers.Get(i);
logger.DebugFormat("Key: {0}, Value: {1}", key, value);
}
CookieContainer container = new CookieContainer();
foreach (var cookie in token.Cookies)
{
logger.Debug("Adding cookie: " + cookie.Name);
logger.Debug("Domain: " + connection.WebUrl.Host);
logger.Debug("Expires: " + cookie.Expires.ToString());
Cookie newCookie = new Cookie(cookie.Name, cookie.Value);
newCookie.Expires = DateTime.MaxValue;
newCookie.Path = "/";
newCookie.Secure = true;
newCookie.HttpOnly = true;
newCookie.Domain = connection.WebUrl.Host;
container.Add(newCookie);
}
e.WebRequestExecutor.WebRequest.CookieContainer = container;
};
}
}
return context;
}
catch (Exception ex)
{
if (context != null)
{
context.Dispose();
}
throw;
}
}
private static CookieInfo GetFedAuthCookie(SharePointClaimsConnection connection)
{
string result = GetSamlToken(connection);
//Take this token and pass it to SharePoint STS
string stringData = String.Format(CultureInfo.InvariantCulture, "wa=wsignin1.0&wctx={0}&wresult={1}",
HttpUtility.UrlEncode(new Uri(connection.WebUrl, "/_layouts/Authenticate.aspx?Source=%2F").ToString()),
HttpUtility.UrlEncode(result));
HttpWebRequest sharepointRequest = HttpWebRequest.Create(new Uri(connection.WebUrl, "/_trust/")) as HttpWebRequest;
sharepointRequest.Method = "POST";
sharepointRequest.ContentType = "application/x-www-form-urlencoded";
sharepointRequest.CookieContainer = new CookieContainer();
sharepointRequest.AllowAutoRedirect = false; // This is important
using (Stream newStream = sharepointRequest.GetRequestStream())
{
byte[] data = Encoding.UTF8.GetBytes(stringData);
newStream.Write(data, 0, data.Length);
}
HttpWebResponse webResponse = sharepointRequest.GetResponse() as HttpWebResponse;
if (webResponse.Cookies["FedAuth"] == null)
{
return null;
}
return new CookieInfo()
{
Cookies = webResponse.Cookies.Cast<Cookie>().ToList(),
};
}
private static string GetSamlToken(SharePointClaimsConnection connection)
{
string result;
Uri STSService = new Uri(connection.SecurityTokenServiceEndPoint, WindowsTransport);
using (WSTrustChannelFactory trustChannelFactory = new WSTrustChannelFactory(
new WindowsWSTrustBinding(SecurityMode.Transport),
new EndpointAddress(STSService)))
{
trustChannelFactory.TrustVersion = System.ServiceModel.Security.TrustVersion.WSTrust13;
trustChannelFactory.Credentials.SupportInteractive = false;
trustChannelFactory.ConfigureChannelFactory<IWSTrustChannelContract>();
//Request Security Token
RequestSecurityToken rst = new RequestSecurityToken();
rst.KeyType = KeyTypes.Bearer;
rst.RequestType = RequestTypes.Issue;
rst.AppliesTo = new EndpointAddress(connection.Realm);
var channel = trustChannelFactory.CreateChannel();
WSTrust13RequestSerializer trustSerializer = new WSTrust13RequestSerializer();
using (Message message = Message.CreateMessage(
MessageVersion.Default, WSTrust13Constants.Actions.Issue,
new RequestBodyWriter(trustSerializer, rst)))
{
Message response2 = channel.EndIssue(channel.BeginIssue(message, null, null));
XmlDictionaryReader reader = response2.GetReaderAtBodyContents();
result = reader.ReadOuterXml();
}
}
return result;
}
I am using WatIn to make the login to a website. I need to get all cookies and set them to HttpWebRequest so that I will be able to download a file from this website (bank). I am using Fiddler to see all the cookies and I can see that I am missing some. If I stop my program (debug) and by hard-code insert all cookies from Fiddler to my cookie it will download my files, so that means 100% that I just need to get the cookie from WatIn and my mission is complete.
So how can I get all the cookies?
My code WaTin:
using (var browser = new IE("https://bankxxx.com"))
{
try
{
browser.WaitForComplete();
try
{
// browser.Visible = false;
browser.TextField(Find.ById("userID")).TypeText(strUser);
Thread.Sleep(1000);
browser.TextField(Find.ById("numID")).Value = strUserId;
browser.TextField(Find.ById("userPassword")).TypeText(strPass);
linkExist = browser.Image(Find.ById("inputSend")).Exists;
if (linkExist) browser.Image(Find.ById("inputSend")).Click();
browser.WaitForComplete();
linkExist = false;
}
catch (Exception ex)
{
successful = false;
clsUtils.WriteToLog("Fail to connect -" + ex.Message, true);
ErrorLog += "Fail to connect -" + ex.Message + Environment.NewLine;
}
//Here i am in side of WebSite
//I tried this too,i getting the same cookie
//CookieContainer cookies23 = browser.GetCookieContainerForUrl(new Uri("bank.com"));
//CookieCollection cookies34 = browser.GetCookiesForUrl(new Uri("bank"));
string cookies = browser.Eval("document.cookie");
CookieContainer _cookies = GeneralUtils.GetCc(cookies, "bank.com");
//then my httpreqest NOT FUll it is working 100% if cookies is good
HttpWebRequest postRequest = (HttpWebRequest)WebRequest.Create("bank.com");
postRequest.CookieContainer = new CookieContainer();
postRequest.CookieContainer = _cookies;.......
}
My GetCc function than build CookieContainer from string and add domain:
public static CookieContainer GetCc(string cookie, string Domain)
{
CookieContainer Cc = new CookieContainer();
string[] arrCookie;
string[] allcookies = cookie.Split(';');
for (int i = 0; i < allcookies.Length; i++)
{
arrCookie = allcookies[i].Split('=');
Cookie TCookie = new Cookie();
TCookie.Name = arrCookie[0].Trim().ToString();
TCookie.Value = arrCookie[1].Trim().ToString();
TCookie.Domain = Domain;
Cc.Add(TCookie);
}
return Cc;
}