C# - HttpClient is not sending any cookies - c#

I am developing two websites names www.web1.com and www.web2.com.
In web1 I am saving a http cookie as below
HttpCookie AuthCookie = new HttpCookie(AppConstants.Cookie.AUTH_COOKIE);
AuthCookie.Path = "/";
AuthCookie.Value = "value1";
Response.Cookies.Add(AuthCookie);
Now what I want is to read this cookie in the second website i.e. web2. I am trying to read it using HttpClient as below
HttpClientHandler handler = new HttpClientHandler();
handler.CookieContainer = new CookieContainer();
HttpClient client = new HttpClient(handler);
response = client.GetAsync("http://www.web1.com").Result;
var cookies = cookies.GetCookies(new Uri("http://www.web1.com"));
This doesn't returns any cookies, checked via Fiddler as well. But if I directly open the www.web1.com and check fiddler then it sends the cookie.
Please see what I am missing so that the cookie is not returned from httpclient.
Thanks,
SB

Not sure if this would work properly in your case but AuthCookie.Domain = "IP/Domain"; should do the job for you.
Having said that there are other alternatives like query string and page post on other domain that might interest you.

You can't get or set cookies for another domain. That would be a huge security issue. (would you want me reading your site's cookies on my site?)
Some related posts:
Create a asp.net authenicated cookie on 1 site for another
I need to get all the cookies from the browser
Create cookie with cross domain
Cross domain cookies
UPDATE: A bit of clarification: As a server, you can't get or set cookies on a client for another domain, which is what you want to do. As a client, you can modify / delete cookies that a server sets for you.
In your example, your server-side code is making the request to web1.com. You are not going to get a cookie for a random client. The client isn't involved at all in your code above.
If I visit web1.com and you set a cookie called "username" with a value of "bob", I can, as a client, modify this cookie to have a value of "admin" and then potentially have admin rights to your site, depending on how you are handling your cookies.

Related

JWT auth with asp.net core to create token and store in http only cookies and angular to call method with header

I am new to JWT with basic idea of how it works. I have set the jwt token inside cookie from my web api.
Response.Cookies.Append("X-Access-Token", foundUser.Token
, new CookieOptions { HttpOnly = true }) ;
Now i am trying to call a web api get request which is marked as authorised from my agular application.
But inside angular i dont have a way to send the cookie. As per few documents i came to know that http only cookies are sent directly with our interference but i am not able to fetch the data with unauthorised error, which means that the token is not being used. I have not included the same in the get method as well. see below.
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
[HttpGet]
public async Task<ActionResult<IEnumerable<Invoice>>> GetInvoices([FromQuery]QueryParameters queryParameters)
{
return await _uOW.InvoiceRepository.GetInvoices(queryParameters);
}
Do i have to add some logic to read the cookie in backend? I didnt find any answer for this.
Please let me know if there is something missing.
Also inside angular i have not written any special code for calling this get. Is that required?
var headerForToken = new HttpHeaders({'Authorization':`Bearer ${sessionStorage.getItem("token")}`});
return this.http.get<any>(this.APIUrl+'Invoices/GetInvoices',{headers:headerForToken });
This is my current approach in which i am using local storage, but i really need to use the http only cookie.
If there is any link for solution or anything that would be really helpfull
Update 1: So we need to add a domain for this. I tried adding domain still it is not visible when i try to see the cookies.
Response.Cookies.Append("X-Access-Token", foundUser.Token
, new CookieOptions { HttpOnly = true, Domain = ".localhost:4200" }) ;

Can you supply Credentials through Webclient in C#?

I need to access a php page that's behind a central authentication server. Using any other means, when I try to access this site, it redirects to the CAS page, awaiting authentication. Which essentially, has me supplying GET variables to the authentication page. (do not want.) Unfortunately, we cannot remove the CAS for this page, because it is a massive security risk.
So my question is, is there anyway to supply the credentials I have to the CAS, store any cookies from that, then using that, access the php page?
my attempt below:
Since I'm using the GET method, I don't need to worry about waiting until I'm at the php page to supply the values, I just need to actually access the page, which we'll call https://site.com/page.php?var1=value1&var2=value2
As WebClient accessing page with credentials suggested, I created a class CookieAwareClient
public class CookieAwareWebClient : WebClient
{
public CookieAwareWebClient()
{
CookieContainer = new CookieContainer();
}
public CookieContainer CookieContainer { get; private set; }
protected override WebRequest GetWebRequest(Uri address)
{
var request = (HttpWebRequest)base.GetWebRequest(address);
request.CookieContainer = CookieContainer;
return request;
}
}
and then the following to submit:
using (var client = new CookieAwareWebClient())
using (var client = new CookieAwareWebClient())
{
var values = new NameValueCollection
{
{"username", "usr" },
{"password", "(passw0rd!)"}, //don't worry. not actual information
};
//This should bring me to the login page, which will upload the values I have given
client.UploadValues("https://site.com/page.php?var1=value1&var2=value2", values);
string result = client.DownloadString("https://site.com/page.php?var1=value1&var2=value2");
unfortunately, this still does not log me into the CAS, and result is returned as the HTML for the CAS.
Does anyone have ANY idea how I fix this? thank you for your help.
I don't know if CAS supports standard HTTP auth out of the box. It is generally forms based.
After being redirected to CAS, you'll want to parse/scrape the page for a few of the hidden form variables. POST those parameters, the username, and the password (along with the cookie that was returned with GET request).
CAS should return an HTTP redirect. (There will be an additional cookie added to the collection: CASTGC cookie.) The webclient should redirect you back to the originally requested resource. Some apps might need two hops to get back.
If you will be polling the resource within the lifetime of the web application's session, make the subsequent calls using the same CookieCollection and you shouldn't have authenticate against CAS again.

.Net cookies keep coming back with expiration of zero

I am having trouble with the .Expires cookie attribute. It keeps coming back with 01/01/0001 12:00 AM, when I read the cookie back.
Here is the code. I added in the retrieve just below the save solely for debugging purposes. The save and retrieve happen in different places in the same file. I purposely did not specify a Domain, as I want the cookie to exist site wide.
The data shows up nicely, just not the expiration.
Note: I am testing under Visual Studio 2012 running under local host using .Net Framework 4.
System.Web.UI.Page oPage = this.Page;
HttpCookie oCookie = new HttpCookie("UserData");
// Set the cookie value.
oCookie.Secure = false;
oCookie["Field1"] = strField1;
oCookie["Field2"] = strField2;
oCookie.Expires = DateTime.Now.AddDays(1);
// Add the cookie.
oPage.Response.Cookies.Add(oCookie);
// Get the cookie.
oCookie = new HttpCookie("UserData");
oCookie = oPage.Request.Cookies["UserData"];
The browser will not send anything to the server except the cookie name and value. All of the other properties (expires, domain, path, httponly, ...) cannot be retrieved on requests after the cookie has been set.
The more accepted way to deal with this is to redirect the user to a login page when they try to access a protected resource and display some message along the lines of "You need to log in to view this page. If you were previously logged in, your session may have expired."
(Also note that you should be re-setting the cookie on every request, so that the user will not be logged out if they continue to use the site. It's not clear from your code whether you are doing this or not.)
I was just doing some more Google searching on my problem and saw this link, another posting here on Stackoverflow.
Cookies are always expired
I am also validating using the construct:
if (cookie != null && cookie.Expires > DateTime.Now)...
As several pointed out, expiration checking happens, if you can no longer retrieve the cookie. That is seriously dumb on whomever constructed this architecture. Yes, maybe there should be RequestCookie and ResponseCookie, the difference being ResponseCookie has no Expiry date.
The person who resopnded to me taught me that it is not just expires but other fields too.
In C# code, if using Form Authentication, You can find if cookie is persistent using below code
bool IsCookiePersistent = ((FormsIdentity)User.Identity).Ticket.IsPersistent;
Here Ticket will return the FormsAuthenticationTicket which has Expiration DateTime property.

mulltiple account cookies on single machine

consider this, If one is user of a Web application
like :
A someone visits SomeWebSite.com as a normal User (registered)
HttpCookie cookie = new HttpCookie("LastVisit");
cookie.Value = DateTime.Now.ToString();
cookie.Expires = DateTime.Now.AddDays(1);
Response.Cookies.Add(cookie);
B visits SomeWebSite.com, using another account as a moderator / admin
HttpCookie cookie = new HttpCookie("LastVisit");
cookie.Value = DateTime.Now.ToString();
cookie.Expires = DateTime.Now.AddDays(1);
Response.Cookies.Add(cookie);
Both cookies belong to same domain, but for two different Accounts. How does browser know Which cookie belongs to which account ? if we use the following code to access it.
if (Request.Cookies["LastVisit"] != null)
{
string lastTimeUserVisited = Request.Cookies["LastVisit"].Value;
}
EDIT: It's my first time ever to work on cookies.
I do appreciate your patience
I don't quite understand the question. A single browsing session won't distinguish between the two cookies. The last cookie that the server sets replaces the previous ones. Obviously, two instances of Chrome running on two different computers don't share cookies and each send their own instance of the cookie to the server in every request.
How does browser know Which cookie
belongs to which account?
It doesn't. The cookie for the second visit overwrites the cookie for the first. If you want that to be different, you have to use different cookie names, e.g. by appending the user ID to the cookie name.
If the users are logged in using the same user account on the computer, they will be using the same set of cookies.
If they are logged in using separate user accounts, they will each have their own set of user folders and thus their own browser settings and their own set of cookies.

Issues overwriting a cookie

Client has a site at a.url.com. Client creates a cookie with host as ".url.com" and path as "/". Client redirects to us at b.url.com. Client has a coding issue that requires us to delete the cookie (long story).
The following code is not adjusting the expiration at all in our test or production environments but is working fine locally.
if (Request.Cookies["cookie"] != null)
{
HttpCookie myCookie = new HttpCookie("cookie");
myCookie.Expires = DateTime.Now.AddDays(-1d);
Response.Cookies.Add(myCookie);
}
Any ideas?
We've figured it out. We needed to add one line of code to manually set the domain. Makes total sense now.
if (Request.Cookies["cookie"] != null)
{
HttpCookie myCookie = new HttpCookie("cookie");
myCookie.Domain = ".url.com";
myCookie.Expires = DateTime.Now.AddDays(-1d);
Response.Cookies.Add(myCookie);
}
is this a third party cookie? If so, the default security settings in IE will prevent cookie writing in the "internet" zone but it is allowed in your local zone.
Here's a hack. I am just posting this in case you find out that you cannot do what you want due to some security issue preventing you handling the issue on the second site.
You could send a request to the first site to clear the cookie via redirect and have that site bounce the user back again. Like I said, this is very hackish (or I suppose marketing would call it inter-site cooperative security feature).
Hopefully, there's a better approach, but at least you have an alternative if no other ones are forthcoming.
If you cannot get it working in C# you might want to consider seeing if you can manipulate the cookies in javascript.
Gary

Categories

Resources