Asp.NET cookie across subdomains not updating and not expiring - cookies

I have 2 subdomains and I need to set and read the same cookie from both websites.
When I use localhost, everything works fine.
When I switch to using valid urls, the cookie infomation is not really being updated when I update it (expire date on logout).
I have the domain of the cookie set to ".mysite.com"
what is wrong?

The answer was to set the domain to the cookie when expiring it on logout
HttpCookie aCookie = Request.Cookies["Token"];
aCookie.Expires = DateTime.Now.AddDays(-1);
aCookie.Domain = ConfigurationManager.AppSettings["CookieDomain"];
Response.Cookies.Add(aCookie);

Try this:
if (Request.Cookies["Token"] != null) {
HttpCookie aCookie = Request.Cookies["Token"];
aCookie.Expires = DateTime.Now.AddDays(-1);
Response.Cookies["Token"] = aCookie;
}
Instead of adding it, set it to the existing cookie.

Your forms authentication setting in the web.config needs to enable cross app redirects:
<authentication mode="Forms">
<forms loginUrl="~/login.aspx" protection="All" timeout="960" name=".ASPXAUTH" path="/" requireSSL="false" slidingExpiration="false" defaultUrl="~/default.aspx" enableCrossAppRedirects="true"/>
</authentication>

Here is my code: (works fine on localhost but not subdomain, never logs the user out because the cookie doesnt get expired)
Login page:
FormsAuthentication.SetAuthCookie(UserName.Text, true);
// set the active collab cookie
Member member = MemberManager.GetMemberByUsername(UserName.Text);
HttpCookie cookie = new HttpCookie("Token", member.Profile.Token);
cookie.Domain = ConfigurationManager.AppSettings["CookieDomain"];
cookie.Expires = DateTime.Now.AddYears(1);
Response.Cookies.Add(cookie);
Globax ASAX
if (HttpContext.Current.Request.Cookies["Token"] != null) {
string token = HttpContext.Current.Request.Cookies["Token"].Value;
if (!string.IsNullOrEmpty(token)) {
// If the user is logged in with a different token
// or not logged in at all
// then log them in with the token from the cookie
if ((MemberManager.CurrentMember != null && MemberManager.CurrentMember.Profile.Token != token) || User == null) {
Member member = MemberManager.GetMemberByToken(token);
if (member != null) {
FormsAuthentication.SetAuthCookie(member.User.UserName, true);
}
}
}
}
Logout Code:
if (Request.Cookies["Token"] != null) {
HttpCookie aCookie = Request.Cookies["Token"];
aCookie.Expires = DateTime.Now.AddDays(-1);
Response.Cookies.Add(aCookie);
}
Web.Config
<machineKey
validationKey="{-snip-}"
decryptionKey="{-snip-}"
validation="SHA1"
decryption="AES" />
<authentication mode="Forms">
<forms name="AuthCookie"
path="/"
loginUrl="~/login.aspx"
protection="All"
timeout="60">
</forms>
</authentication>

Related

Grafana OAuth with keyclock and flask

I am trying to make the Keyclock SSO work with the webapp and Grafana which is embedded in.
I have made the grafana integerate with the keyclock and I am able to login using the keyclock into grafana. But when I embed the grafana as inframe into the webapp, and log into the webapp with keyclock, am shown the error as
login.OAuthLogin(missing saved state)
This is my flask config
{
"web": {
"issuer": "http://localhost:8080/realms/internal",
"auth_uri": "http://localhost:8080/realms/internal/protocol/openid-connect/auth",
"client_id": "flask",
"client_secret": "nlY4o3kIrReiwwsYo0FrKFDHIZvfdXd5",
"redirect_uris": [
"http://localhost:5000/*"
],
"token_uri": "http://localhost:8080/realms/internal/protocol/openid-connect/token",
"token_introspection_uri": "http://localhost:8080/auth/realms/internal/protocol/openid-connect/token/introspect",
"userinfo_uri": "http://localhost:8080/realms/internal/protocol/openid-connect/userinfo"
}
}
Following is my grafana config
[auth.generic_oauth]
enabled = true
name = OAuth
allow_sign_up = true
client_id = grafana
client_secret = CA6OIr8z9v3ZPY4yhPWMSwZWJIPWaRK7
scopes = openid email profile
;email_attribute_name = admin#test.com
;email_attribute_path = admin#test.com
auth_url = http://localhost:8080/realms/internal/protocol/openid-connect/auth
token_url = http://localhost:8080/realms/internal/protocol/openid-connect/token
api_url = http://localhost:8080/realms/internal/protocol/openid-connect/userinfo
;allowed_domains =
;team_ids =
;allowed_organizations =
role_attribute_path = "contains(roles[*], 'Admin') && 'Admin' || contains(roles[*], 'Editor') && 'Editor' || 'Viewer'"
;tls_skip_verify_insecure = false
;tls_client_cert =
;tls_client_key =
;tls_client_ca =
I have the following settings for the cookies and embedding
cookie_samesite = lax
allow_embedding = true
I am getting an 500 Error auth to the grafana is redirected
SameSite=Lax:
Only send the cookie in a first-party context (meaning the URL in the address bar matches the cookie domain). Do not send it with the following cross-origin requests: non-GET, AJAX, iframe, image requests etc. It saves the user from cross-site request forgery.
So Lax is blocking cookie "propagation" to iframe in your use case. None is better option in this case for cookie_samesite Grafana config.

NextJS middleware can fetch httpOnly cookies only during development?

When Using the NextJS _middleware.js cookie is fetched by it during development in localhost, but as soon as I deploy onto vercel it stops fetching the cookie.
The Cookie is httpOnly and the cookie is present on the website but is not being fetched by the middleware in production.
Here is my middleware code
import { NextResponse } from "next/server";
export async function middleware(req) {
let token = req.cookies["refreshToken"];
console.log(token);
const { origin } = req.nextUrl
const url = req.url
if (url.includes('/profile') && !token) {
return NextResponse.redirect(`${origin}/`)
}
if (token && url.includes('/profile')) {
return NextResponse.next()
}
}
Any Suggestions? or does it not work cross site ?, but I am able to store the cookie, keep that in mind.
It might be a cross-site request issue. If your backend is hosted on a different domain and you set the cookie with the SameSite attribute set to lax or strict, your frontend code won't have access to it (see MDN).

Why aren't cookies passed in a request from a sub-domain?

Domain wide cookies are not passed in requests from a subdomain.
The cookie is originally set from www.mydomain.com. I'm setting the cookie domain to ".mydomain.com" and the path to "/", so that the cookie will be available to my main domain and any subdomains.
HttpCookie cookie = new HttpCookie("MyCookie");
cookie.Domain = ".mydomain.com";
cookie.Path = "/";
cookie.HttpOnly = true;
cookie.Secure = true;
cookie.Values.Add("MyCookie", "Test Value");
cookie.Expires = DateTime.Now.AddYears(1);
HttpContext.Current.Response.Cookies.Add(cookie);
The cookie gets sent back in any subsequent requests to www.mydomain.com, but requests from sub.mydomain.com do not include my cookie.

How to set expiration date to client cookies?

I configured Identity Server:
public void Configuration(IAppBuilder app)
{
var factory = new IdentityServerServiceFactory().UseInMemoryClients(new Client[] {
new Client()
{
ClientName = "MyClient",
ClientId = "MyClientId",
Enabled = true,
Flow = Flows.Implicit,
RedirectUris = new List<string> { "MyClientServer/callback" },
};
});
}
and client server:
public void Configuration(IAppBuilder app)
{
var cookieOptions = new CookieAuthenticationOptions();
cookieOptions.AuthenticationType = "Cookies";
app.UseCookieAuthentication(cookieOptions);
var authenticationOptions = new OpenIdConnectAuthenticationOptions() {
Authority = "https://MyIdentityServer/core",
ClientId = "MyClientId",
SignInAsAuthenticationType = "Cookies",
UseTokenLifetime = true,
RedirectUri = "MyClientServer/callback"
});
app.UseOpenIdConnectAuthentication(authenticationOptions);
}
When user login with "Remember Me" option Identity cookie has expired date:
idsvr.session expires 04 October ...
But client cookie does not:
.AspNet.Cookies at end of session
What should I do to set the same expiration date to client cookie?
UPDATE:
I can set any expiration date in client application:
authenticationOptions.Provider = new CookieAuthenticationProvider()
{
OnResponseSignIn = (context) =>
{
var isPersistent = context.Properties.IsPersistent;
if (isPersistent) // Always false
{
context.CookieOptions.Expires = DateTime.UtcNow.AddDays(30);
}
}
};
But I cannot determine when to set expiration date. It should be set only when user selects "Remember Me", but IsPersistent option always false on client side.
The problem exists on simple boilerplate project too:
https://identityserver.github.io/Documentation/docsv2/overview/mvcGettingStarted.html
UPDATE2:
I need client cookie to be persistent because of bug in Safari - https://openradar.appspot.com/14408523
Maybe some workaround exists, so I can pass expiration date in callback from Identity to Client?
UPDATE3:
Actually, our Identity and Client servers have same parent domain like app.server.local and id.server.local. Maybe I can pass expiration date via additional cookie that belongs to parent domain (.server.local)? But I have no idea where it can be written on Identity, and where it can be applied on Client.
A cookie issued by IdentityServer and a cookie issued by a client application are not linked in any way. IdentityServer does not have any control over cookies in a client application.
When you log in to IdentityServer, you are issued a cookie that tracks the authenticated user within IdentityServer. This saves the user from entering their credentials for every client application, facilitating single sign on.
By default this cookie lasts for that session (so it expires once the browser closes), otherwise if you set "remember me" it will last for a set number of days, across sessions.
A cookie in a client application would be issued upon successful verification of an identity token from IdentityServer. This cookie can have any expiration time, any policy, any name. It's completely controlled by the client application. In your case client cookie expiration can be set in the CookieAuthenticationOptions in your client application.
You need to handle the cookie auth events. The open id middleware just creates an auth cookie, so you can handle all aspects of this cookie from those events. You'll need to look at the events and with a little trial and error you should be able to manage the cookie lifetime.
You can do it at the java-script by using following code in here I have created this cookie to expires within 14 days.
var exdate = new Date();
exdate.setDate(exdate.getDate() + 14);
document.cookie = "yourcookie=" + yourCookieValue + ";expires=" + exdate.toUTCString() + ";";

RestSharp response unauthorized

I am new to web based solutions. I am hitting a rest url using RestSharp library.
My code is as follows:
var cleint = new RestClient("http://REST_URL");
cleint.Authenticator = new HttpBasicAuthenticator("username", "password");
var request = new RestRequest();
request.Method = Method.GET;
request.Resource = "0.json";
IRestResponse response = cleint.Execute(request);
if (response != null && ((response.StatusCode == HttpStatusCode.OK) &&
(response.ResponseStatus == ResponseStatus.Completed)))
{
// var arr = JsonConvert.DeserializeObject<JArray> (response.Content);
}
The url returns a json file, when I hit it manually. But I want to use a C# console application to get the json file and save it to the disk. I am getting an unauthorized response when I run the above mentioned code:
response.ResponseStatus= "Unauthorized"
This is all it needed..
client.Authenticator = new NtlmAuthenticator();
So if your IIS settings have Windows Authentication set as enabled, this is what you are going to need, Http Basic authentication is not enough to by pass the server security