Is there a way to use CloudFront signed cookies in HTML - cookies

I'm trying to just get started in my understanding on how the CloudFront with signed cookies work.
I have an HTML file that is tied to my CloudFront distribution:
http://blahblahbla.cloudfront.net/lebron.jpg
If I'm reading the instructions properly I have to add something to my Bucket policy for my S3 bucket that I'm using as the origin:
{
"Statement":[
{
"Resource":"base URL or stream name",
"Condition":{
"DateLessThan":{
"AWS:EpochTime":ending date and time in Unix time format and UTC
}
}
}
]
}
After that it looks like I have to add the following to somewhere:
Set-Cookie: Domain=d111111abcdef8.cloudfront.net; Path=/images/*; Secure; HttpOnly; CloudFront-Expires=1426500000
Set-Cookie: Domain=d111111abcdef8.cloudfront.net; Path=/images/*; Secure; HttpOnly; CloudFront-Signature=yXrSIgyQoeE4FBI4eMKF6ho~CA8_
Set-Cookie: Domain=d111111abcdef8.cloudfront.net; Path=/images/*; Secure; HttpOnly; CloudFront-Key-Pair-Id=APKA9ONS7QCOWEXAMPLE
The above is from the documentation. Do I add the above in between my <head> tags or somewhere else?
I see a lot of documentation for Python and even C# but i'm just trying to do a simple test using the signed cookies with a simple HTML page. Is that even possible?
It goes without saying that, I'm still pretty far from understanding this, so any help regarding the Bucket policy and the keys issue would be appreciated.

Related

Is cookie with longer domain are listed before cookie with shorter domain?

Say for example I had an application sending the following HTTP headers to set to cookie named "key1":
Set-cookie: key1=111; Domain=cc.net
Set-cookie: key1=222; Domain=bb.cc.net
Set-cookie: key1=222; Domain=aa.bb.cc.net
If I access aa.bb.cc.net on the server, so I have three cookies named "key1",but How are these three cookies arranged? Is cookie with longer domain are listed before cookie with shorter domain?
What is the specification of rfc?

Samesite=Strict cookies are not included in 302 redirects when user clicks link from a different domain

A customer will link to one of our webpages on their site: customer.site/links.html
A person clicks that link and gets sent to our.site/webapp/handlerequest.aspx?someparam=somevalue
The value of someparam is set in a cookie with SameSite=Strict and then uses a 302 redirect to another page on the same domain:
Request URL: https://our.site/webapp/handlerequest.aspx?someparam=somevalue
Request Method: GET
Status Code: 302
Remote Address: ...
Referrer Policy: strict-origin-when-cross-origin
cache-control: private
content-length: ...
content-type: text/html; charset=utf-8
date: ...
location: /webapp/someotheraction
server: Microsoft-IIS/10.0
set-cookie: someparam=somevalue; expires=Thu, 17-Mar-2022 14:41:13 GMT; path=/; secure; HttpOnly; SameSite=Strict
strict-transport-security: max-age=31536000
x-frame-options: SAMEORIGIN
The browser does NOT include this cookie on the 302 redirect to /webapp/someotheraction.
This only starting happening when we specifically change our code to set this cookie to SameSite=Strict.
This occurs in Chrome, Firefox, Edge, and IE (old IE)
Is this on purpose? Why? Since we are going from one request on the domain to another request in the same domain, shouldn't the SameSite=Strict cookies be included? Does this have anything to do with the referer policy defaulting to strict-origin-when-cross-origin? https://www.w3.org/TR/referrer-policy/ doesn't say anything about cookies
This is a cross-site request because the initial navigation was cross-site (from customer.site to our.site). Strict cookies are never sent on cross-site requests. It doesn't matter that the request gets redirected (in this case, to another URL on our.site), just the fact that the user clicked on a cross-site link means the request is cross-site.
As for why this is the case, it's because the origin responsible for initiating the navigation is important in preventing cross-site request forgery (CSRF). Imagine if https://evil.site had a link to https://bank.site/transfer-funds which redirects to https://bank.site/transact. We wouldn't want Strict cookies to be send to the /transact endpoint after the redirect, even if it was redirected to by the same site, because the initiating origin is cross-site.

Cookie is not stored in the brower, cross domain GET request

I have a domain (say cookiebaker.com) that provides files using GET requests. Whenever a request is made the cookiebaker server adds a set-cookie header to the file response.
Here is an example header (Max-Age is set for 1 month in the future):
set-cookie: cookie_name=cookie_value; Max-Age=2592000; secure; HttpOnly; SameSite=Lax
Now when I call cookiebaker.com from a different domain (say munchies.com) I can see the set-cookie header in the GET response, but munchies.com does not store the cookie. I don't see the cookie in dev tools, and it is not uploaded in subsequent requests.
I am aware that I have to set the "withCredentials" flag to true when performing the GET request, but this didn't help in my case.
Here's my stripped down munchies.com code:
let request = new XMLHttpRequest();
request.open('GET', "https://cookieBaker.com?param=value");
request.withCredentials = true; // Tell the browser to receive cookies
request.send();
Is there anything else that could block the cookie from being stored in the browser? These are all my access Control headers included in the GET response (localhost is the "real" name of munchies.com for my testing):
access-control-allow-credentials: true
access-control-allow-headers: Authorization, Content-Type
access-control-allow-methods: OPTIONS, GET, POST, PUT, PATCH, DELETE
access-control-allow-origin: http://localhost
access-control-expose-headers: X-WP-Total, X-WP-TotalPages
You have explicitly set SameSite=Lax on the cookiebaker.com cookie, which will restrict it from being sent in a cross-site context, e.g. a fetch() originating from munchies.com.
For an explicit cross-site cookie, you should use SameSite=None;Secure. For more in-depth implementation detail, see https://web.dev/samesite-cookie-recipes

Cognito logout does not work as documented

I have a Cognito user pool configured with a SAML identity provider (ADFS) and I'm able to sign it as a federated user (AD) but sign out does not work.
Following the documentation, I make a GET request to
https://my-domain.auth.us-west-2.amazoncognito.com/logout?client_id=63...ng&logout_uri=http:%2F%2Fyahoo.com (using some public logout uri), from my client (an AngularJS 1.x app), and I get back a 302 with a Location header like
https://my-domain.auth.us-west-2.amazoncognito.com/login?client_id=63...ng&logout_uri=http:%2F%2Fyahoo.com
(In fact there I see 2 requests like the above).
When I log back in (thru ADFS) it does not prompt for my AD credentials, i.e. seems that I'm not logged out.
My user pool is configured as described here (see step 7), where the Enable IdP sign out flow is checked, which is supposed to log the user out from ADFS as well.
Any suggestions?
Thanks.
General
-------
Request URL: https://my-domain.auth.us-west-2.amazoncognito.com/logout?client_id=63...ng&logout_uri=http:%2F%2Fyahoo.com
Request Method: GET
Status Code: 302
Remote Address: 54.69.30.36:443
Referrer Policy: no-referrer-when-downgrade
Response Headers
----------------
cache-control: private
content-length: 0
date: Fri, 20 Apr 2018 21:31:12 GMT
expires: Thu, 01 Jan 1970 00:00:00 UTC
location: https://my-domain.auth.us-west-2.amazoncognito.com/login?client_id=63...ng&logout_uri=http:%2F%2Fyahoo.com
server: Server
set-cookie: XSRF-TOKEN=...; Path=/; Secure; HttpOnly
set-cookie: XSRF-TOKEN=""; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/; Secure; HttpOnly
status: 302
strict-transport-security: max-age=31536000 ; includeSubDomains
x-content-type-options: nosniff
x-frame-options: DENY
x-xss-protection: 1; mode=block
Request Headers
---------------
:authority: my-domain.auth.us-west-2.amazoncognito.com
:method: GET
:path: /logout?client_id=63...ng&logout_uri=http:%2F%2Fyahoo.com
:scheme: https
accept: application/json, text/plain, */*
accept-encoding: gzip, deflate, br
accept-language: en-US,en;q=0.9
authorization: Bearer eyJra...
cache-control: no-cache
origin: https://localhost:8443
pragma: no-cache
referer: https://localhost:8443/logout
user-agent: Mozilla/5.0...
This redirect happens whenever logout_uri parameter doesn't match exactly what's listed among Sign out URL(s) in AWS Cognito User Pools App client settings configuration.
Cognito allows logout with either logout_uri or with the same arguments as login (i.e. redirect_uri and response_type) to log out and take the user back to the login screen. It seems that whenever logout_uri is invalid, it assume the re-login flow, does this redirect, and then reports an error about missing login arguments.
As for SAML, I don't know, but guessing that it doesn't work because there was actually an error, just not properly reported.
The /logout endpoint signs the user out.It only supports HTTPS GET. It is working
Sample Requests - Logout and Redirect Back to Client
It clears out the existing session and redirects back to the client. Both parameters are required.
GET https://<YOUR DOMAIN NAME>/logout?
client_id=xxxxxxxxxxxx&
logout_uri=com.myclientapp://myclient/logout
Also make sure that Logout URL is same as SIGNOUT URL in AWS Cognito APP too.
for more information, refer AWS LOGOUT Endpoint
Finally I was able to fix this issue. I found the actual cause of the issue from the event viewer of my windows server 2012 R2. It says the following details about the failed sign out flow.
The SAML Single Logout request does not correspond to the logged-in session participant.
Requestor: urn:amazon:cognito:sp:userpoolid
Request name identifier: Format: urn:oasis:names:tc:SAML:2.0:nameid-format:persistent, NameQualifier: SPNameQualifier: , SPProvidedId:
Logged-in session participants:
Count: 1, [Issuer: urn:amazon:cognito:sp:userpoolid, NameID: (Format: , NameQualifier: SPNameQualifier: , SPProvidedId: )]
User Action
Verify that the claim provider trust or the relying party trust configuration is up to date. If the name identifier in the request is different from the name identifier in the session only by NameQualifier or SPNameQualifier, check and correct the name identifier policy issuance rule using the AD FS 2.0 Management snap-in.
The Error clearly says that the name identifier in the request is different from the name identifier in the session only by NameQualifier. I have corrected this error in the claim issuance tab of relying party trusts by adding the rule as below. The below rule replace the user#myadfsdomain to simply user when issuing the claim.
c:[Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname"]
=> issue(Type = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier", Issuer = c.Issuer, OriginalIssuer = c.OriginalIssuer, Value = RegExReplace(c.Value, "(?i)^myadfsdomain*\\", ""), ValueType = c.ValueType, Properties["http://schemas.xmlsoap.org/ws/2005/05/identity/claimproperties/format"] = "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent");
Besides this i have forgot to check in the enable signout flow in the cognito configuration which caused the problem. Logout started working seamlessly for me.
From documentation here
https://docs.aws.amazon.com/cognito/latest/developerguide/logout-endpoint.html
If you want
And your login url is like
"https://xxxx.auth.eu-west-1.amazoncognito.com/login?client_id=1234&response_type=token&scope=aws.cognito.signin.user.admin+email+openid+phone+profile&redirect_uri=http://localhost:3000/"
Then your logout url is like
"https://xxxx.auth.eu-west-1.amazoncognito.com/logout?client_id=1234&logout_uri=http://localhost:3000/";
Note the difference
login > login? and redirect_uri
logout > logout? and logout_uri
Those redirect / logout uri must match what you have configured inside Cognito.
If you don't do it right, you may get strange errors like
error=unauthorized_client
or
Required String parameter 'response_type' is not present
and who knows what else. :o)
My solution below is based on -
https://github.com/nextauthjs/next-auth/discussions/3938#discussioncomment-2165155
I am able to solve the issue with few changes-
in signout button upon clicking i will call handleSignOut
function handleSignOut() {
const clientId = 'paste your AWS COGNITO CLIENT ID';
const domain = 'paste your AWS COGNITO DOMAIN';
window.location.href = `${domain}/logout?client_id=${clientId}&logout_uri=http://localhost:3000/logout`
}
In Aws cognito-> app integration -> app client settings -> signout url
keep the following url-
http://localhost:3000/logout
in pages create a seperate page called logout and keep following code-
import { useEffect } from "react"
import { signOut } from 'next-auth/react'
export default function SignoutPage() {
useEffect(() => {
setTimeout(() => {
signOut({ callbackUrl: window.location.origin });
}, 1000);
}, []);
return (
<>
<div className="loader">
Loading..
</div>
<style jsx>{`
.loader{
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
transform: -webkit-translate(-50%, -50%);
transform: -moz-translate(-50%, -50%);
transform: -ms-translate(-50%, -50%);
}
`}</style>
</>
)
}
click signout it will log you out
#RequestMapping(value = "/logout", method = RequestMethod.GET)
public void logout(HttpServletRequest request, HttpServletResponse response) {
LOGGER.info("Logout controller");
try {
Cookie awsCookie = new Cookie("AWSELBAuthSessionCookie-0", "deleted");
awsCookie.setMaxAge(-1);
awsCookie.setPath("/");
response.addCookie(awsCookie);
Properties appProperties = new Properties();
applicationPropertyConfigurer.loadProperties(appProperties);
response.sendRedirect(appProperties.getProperty("logout.url"));
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate, max-age=0");
response.setHeader("Pragma", "no-cache");
response.setDateHeader("Expires", -1);
request.getSession().invalidate();
} catch (IOException e) {
LOGGER.error("Exception in redirecting to logout.url URL", e);
}
}
//https:/domain_name.auth.us-west-x.amazoncognito.com/logout?response_type=code&client_id=&redirect_uri=redirect_uri_should_be_present_in_cognito_user_pool_Callback URL&state=STATE&scope=openid

Cors issues with angular dart - cookies not set

I work on a app using angular.dart at the clientside and dart in the serverside.
I have write a login rest entrypoint and want to set cookies the header was in the response but the cookies are not set.
set-cookie:app-user=533c1470a2658184a7625d7d; Expires=Tue, 8 Apr 2014 9:15:47 GMT; Domain=.ballr.eu; Path=/
set-cookie:app-tokn=530fa71b615e168787a7cb5b5c589a5601065e1e3f921d4b770c784394de3a42; Expires=Tue, 8 Apr 2014 9:15:47 GMT; Domain=.ballr.eu; Path=/
I try to check my headers or my value set in cookies, but to my mind is good
headers :
request.response..statusCode=HttpStatus.OK
..headers.set(HttpHeaders.CONTENT_TYPE, 'text/plain: charset=UTF-8')
..headers.add("Access-Control-Allow-Methods", "OPTIONS, GET, POST, PUT, DELETE")
..headers.add("Access-Control-Allow-Headers", "origin, x-requested-with, content-type, accept")
..headers.add("Access-Control-Allow-Origin", "*");
cookies :
static setCookie(HttpRequest request, String key, String value, DateTime duration) =>
request.response.cookies.add(new Cookie(key, value)..path = '/'
..expires = duration
..domain = '.app.eu');
I follow some threads on stackoverflow and google groups and I think it's a problem of "withCredientals" a value I have set in an another projet (angular/Java) but I don't find this parameter on angular.dart.
Can you help me to find it or have you somes ideas?
Thank you for your help/time
I'm not sure if I understand you question correctly but maybe this is what you are looking for:
(on the client)
var request = new HttpRequest()
..open("POST", uri.toString(), async: true)
..withCredentials = true // seems to be necessary so that cookies are sent
EDIT
I missed that this is about Angular. This needs a slightly different approach.
If you use the Angular http service you have a parameter
class MyController {
Http _http;
MyController(this._http) {
_http.getString('someurl', withCredentials: true).then((e) => ...);
// or _http.request('someurl', method: 'POST', withCredentials: true).then((e) => ...);
}
}