Apigee - setting cookie in the redirect request header of Apigee that was set earlier by the application - cookies

Scenario 1: Working fine
The application receives all the requests through Azure App Gateway. The application sets some value for the session cookie "JSESSIONID" in the response of first "/login" endpoint (set by Spring security). This same JSESSIONID cookie value is then used in the request header of "/login?code=<some_code>&state=<some_state>" api, which is the callback url from the Authorisation server. So, in this case, the auth server is able to identify the client based on same session cookie value. We can infer that Azure app Gateway sends the cookie forward. There is no specific settings done in App Gateway.
Scenario 2: Issue
Now the application receives the request through Azure App Gateway from Apigee. The callback url is also set to the apigee url. The application sets some value for the session cookie "JSESSIONID" in the response of first "/login" endpoint. But when the callback url "/login?code=<some_code>&state=<some_state>" is invoked after Auth server validation success, there is no "JSESSIONID" in the request header. So, possibly Apigee is stripping of this cookie.
The other cookies like "SameSite", "ADRUM_BTa" and "ADRUM_BT1" are passed in the request header of the callback url in both the scenarios.
Could someone please help here, if there is any settings change that needs to be done in Apigee so that it sends the cookie in the request header of callback url.

This was resolved by setting the session cookie path in the Application equal to the URI backend path of the Apigee configuration.
server.servlet.session.cookie.path=/backend/path/configured/in/apigee/proxy
As the session cookies are always set based on path. By default, without the above code, the session cookie path was set to the server context path of the application.

Related

How can you access cookies on a static S3 site behind a CloudFront distribution?

So I'm trying to deploy my website which works well when in a local environment, but when it is deployed to Cloudfront, it can't seem to access cookies.
My frontend tech stack is as follows: Angular site hosted on S3, cloudfront distribution in front of it, custom domain name with a valid ssl certificate.
When the user navigates to the login page, they can successfully submit the forum, and the server responds with a JWT token in the Set-Cookie header.
After this though, in the angular site it says that the access-token cookie does not exist. The strange part here is that on subsequent requests, the access-token cookie is in fact forwarded back to the backend. (In the image below, the login button was pressed again, so the response cookie is the same as the request cookie.)
I've ensured that HttpOnly is not set, and that the frontend and backend are both hosted under the same root domain frontend.root.com and api.root.com.
Cloudfront has been configured to forward the access-token cookie:
cache policy:
origin request policy (note that it still did not work when I had this set to forward all cookies and not just the access token):
Response headers settings:
So in my angular site, after the /login api call resolves, I use the ngx-cookie-service to check and try to retrieve the cookie.
this.cookieService.check('access-token'); // checks if it exists, returns false
this.cookieService.get('access-token'); // returns '' meaning the cookie does not exist
Any ideas on how to resolve this issue and access the cookies from within my angular site? I can provide more information on my configurations if needed. Thanks!
As you can barely make out in the screenshot the Cookies have the domain set as something starting with a suggesting that it is api.root.com, most importantly it is not frontend.root.com and not root.com.
The server needs to set the domain of the cookie to root.com for it to be available to all subdomains of it.

Using JWT authentication with Django/DRF and Storing JWTs in HttpOnly Cookies

I am trying to build a web app using Django and DRF at the back-end and ReactJs at the front end and I want to keep them separate (i.e. avoid Server Side Rendering).For authentication purposes, I want to employ JWT and I am using djangorestframework-jwt for that. I have read it at several places that it is not secure to store JWTs in the local storage so I am trying to use HttpOnly cookies for that. One can achieve that by configuring the django server to send HttpOnly by overriding the following default settings of the drf-jwt package in the settings.py file of your project JWT_AUTH = { 'JWT_AUTH_COOKIE': '<cookie name>', } which is set to none by default. The server sends the httpOnly cookie as anticipated but there are a few issues I am facing:
1.Same Domain Restraint
I am aware that httpOnly cookies wont be attached to the request headers unless the request is being made to the server which is hosted on the some domain. In my case I am using localhost:8000 for django and localhost:3000 for my react project so the browser doesnt attach the cookie as the request is made to a different port. I tried running both app on port 3000 simultaneously, and the browser did attach the cookie in the header and I did get the a 302 response from the server. However, it opened door to all sorts of problems due domain clash. I reckon I can solve this problem using nginx reverse proxy or something like that but I am not sure about it. Do guide me how can I serve both apps on the same host during the development.
2. Token Refresh Problem
When I refer to the view setup to refresh the token, I run into a bad request error even when the browser does attach the cookie along the request header. This is the server response in the browser
{"token":["This field is required."]}
Thanks if for reading it all the way down here!
In order for things to be secure:
You need CORS (Quickstart: CORS_ALLOWED_HOSTS=["http://localhost:3000"], CORS_ALLOW_CREDENTIALS=True)
The short-lived token (session) cookie (5-15mins), should NOT have HTTP-ONLY setting
The refresh token cookie SHALL have HTTP-ONLY setting
Then your basic flow is:
On login Django creates session token and sends it
Your SPA reads the cookie and adds its value to the authorization header (Authorization: JWT ...token...)
Any request to Django should be made with that Authorization header
The refresh flow is:
Send a request to the refresh token endpoint following the documentation of the library you use
Django then reads the HTTP-ONLY cookie and verifies it
If valid, Django sends a new refresh token as HTTP-ONLY cookie along with a new short-lived token session cookie
Once the refresh token has expired, you log the user out.
An article here goes into detail using GraphQL, but the cookie part and handling of most of the frontend code you should be able to adapt to REST.

OIDC js library reponse cookies are not stored and not attaching for subsequent requests

I am using authcodeflow with PKCE.
Using OIDC js library in the frontend, making calls to adfs getting an auth code and then calling my backend api. The backend api which calls adfs server get the access token and the backend api returns the token as a cookie to the frontend. I can see the cookie in response headers. but That cookie is not stored in browser and not getting added for subsequent requests. I have tried with samesite with all modes -> Lax, None,Strict and not setting.
Is this an issue with OIDC js library or is it blocking the cookies to store in browser?
Update:
Below are the observation with my analysis
Since the OIdc-client-js does not have an option to set flag "withCredentials" to true for the requests. There are no cookies send in the request and response cookies are ignored for the cross origin requests.This changes are marked as enhancement and still not completed in thier github repo.
https://github.com/IdentityModel/oidc-client-js/issues/1062
Is there any way to achieve with this library? or any other libraries for OIDC js
https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/withCredentials
So you are issuing a cookie from an API domain that is a sibling of the WEB domain:
web.mycompany.com
api.mycompany.com
Cookie domain = .mycompany.com
POSSIBLE CAUSES FOR COOKIE BEING DROPPED
Maybe it is the withCredentials flag or maybe due to a lack of user gesture, since the user has not done anything explicit to navigate to api.mycompany.com, such as a browser navigation or clicking a link?
FORCING WITHCREDENTIALS
You can override the prototype like this in order to add the withCredentials property. This is a little hacky but you could limit usage based on the URL and it should let you know whether setting withCredentials resolves your problem:
let open = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function(method, url) {
open.apply(this, arguments);
this.withCredentials = true;
}
PROXYING VIA WEB DOMAIN WILL HAVE FEWER COOKIE ISSUES
In my blog post I do something similar to proxy messages containing a refresh token. I use the web's exact domain though, rather than using an API subdomain. This will never be impacted by browser restrictions.

ember cookie vs server cookie

I am using Ember and Ember-simple-auth. This question is to clear my confusion related to cookies etc.
I have configured ember storage to Cookie.
My server is sending a cookie to be saved at client side. i.e
Set-Cookie: dejavu.session=WwwLQjdfOoNz_-bhyYpBLvzew7IUaJuu; Path=/; Expires=Mon, 28-May-2018 15:59:30 GMT
I have understanding that
browser automatically captures the cookie from set-cookie in header (mean it should be visible in dev tool)
browser automatically add this cookie in subsequent requests.
I don't need to do anything extra with Ember Simple Auth as server cookie is by default handled by browser.
Based on this understanding, in Chrome inspector I just see one cookie of ember-simple-auth and nothing else.
My questions are:
1- Should I see a separate cookie (the one sent from server) in dev tool along with Ember cookie (set by Ember simple Auth)? or my server cookie has to be embedded in Ember Cookie? I actually don't see server cookie on my dev tools so I am confused.
2- Is this right concept that ember cookie is storage for Ember but server cookie is the one that browser will capture and send in header in subsequent requests?
ok. I found the solution after spending alot of testing and exploration.
Answer to my both questions is:
There is a bug in chrome dev tools that doesn't show the cookie sent from server. We don't need to embed server cookie in ember cookie. Browser manages cookies itself. Only server has to send a cookie and then browser will manage it e.g discard it if it expires and then automatically add it to header of each subsequent requests to be sent via api. We can see the cookie as request is sent, in our dev tools 'Network' tab under request headers.
With session cookie and Ember-simple-auth we don't need to set authoriser in header (for adding cookie in header) as this will override the session cookie (that was set by browser).
So when using Ember-simple-auth and session authentication, correct flow is:
add addon
setup authenticator (follow github docs)
don't set authorizer (as told in docs)

PHONEGAP/WP8: FileTransfer not sending session cookies

The server I'm using sends the session id with a http-only cookie.
To make this working on WP8, I already enabled cookies in the internet explorer settings of the device. This works well for all my AJAX-requests.
But now i have to download a file from the server, therefore I'm using the file-transfer plugin, but i always get HTTP Status 401 - Http Request not attached to a session
Is there any way to fix this issue, so that the cookie header containing the JSESSIONID is sent with the download request?