Nginx - set cookie from one url to another for different users - nginx

I'm trying to set up hortonworks schema-registry with openresty.
we have google oauth enabled for our schema-registry ui. The google oauth passes a cookie called "_token" to /ui and all other subsequent paths except /api
This is because we may want to hit /api directly as well. (without google authentication).
The problem is since /api is exluded from the list, I'm unable to pass the cookie "_token" to any of the requests under /api
In my access_by_lua , there is a condition where I check for the cookie,
if the cookie is present - the user is authenticated and then he can move ahead
if not - we do some other checks to validate the request, and pass it ahead accordingly or return an error statement
My question is, if I want to pass the cookie from /ui to /api, how do I go ahead with it?
Also , the cookie should be set only for that particular user so that my other apps can communicate quickly.
What I've tried till now:
I tried setting a global cookie _token after reading it from the /ui path.
This doesnt seem to work since it sets the cookie for all requests (even the ones coming from apps) and the value of the cookie is static based on the first _token it receives from /ui

Related

Checking Nginx cookie's data does not work as expected

Although I have been reading and testing many things I could not get a working solution. I want to do something simple, I want to restrict access to some folders to only logged users. If an user is not logged it should get a redirect to the login page.
I do not want to serve files directly using another script. I want to serve files only to authenticated files, I know that it is possible because I saw some websites like Dropbox (not sure if they use nginx) and other services (with nginx in the headers) do not allow direct access to public files without being logged.
I guess that once the user is authenticated I should add a cookie in the header in the backed so I should be able to check it in Nginx. But I do not know if I can set the cookie and do the check entirely in Nginx
I need to whitelist login and register urls. Because if I check if one cookie exists in the request and it does not exist, I will enter into an infinite loop in the login/register urls
If the cookie does not exist or is not valid, it should redirect user to the login page
I checked the following question which is almost the same as mine:
And I have been trying the next config:
location ~* ^/assets/users/images/(.*)$ {
if ($cookie_cookieafterlogin != "secret_value") {
return 301 https://example_domain.com/login;
}
}
I must say that I am a newbie to Nginx and I am starting to learn now. So the above code is partially working because it blocks direct access to anymous access but it also blocks access for logged users, so I think that I am not setting properly the cookie in my web app.
Once the user is authenticated I am sending in the header my cookie data and checking headers in the browser I can see this:
Set-Cookie cookieafterlogin=secret_value; expires=Sun, 13-Jun-2021 ....
Anyone could say me where is my mistake?
Thanks in advance!

Create Separate Cache for every URL in FastCGI

Problem with FastCGI Cache
Currently, the Query URL is like this.
Correct API URL: example.com/api/123456 (TRUE)
Wrong API URI: example.com/api/1234885 (This also gives True Because it's serving the cached version)
My Use Case:
Upon every request to the webserver by the end-user. The webserver requests my API End Point which matches the API Key and Domain Name then authenticates it and makes the function work and serve the user.
Problem:
When the API hits for the first time with the correct API Key. It returns TRUE. Which is cached and stored.
If another user trying with an Invalid or wrong API key. It keeps serving the cached version (True Value) instead of querying from the database.
What I want to Achieve? How to save example.com/api/123456 and example.com/api/123888 as different cached version.
Because I don't wanna authenticate someone with the wrong API Key because of cache.
Please Share alternative ideas if you have.

Keep Google Client ID after domain has been changed

We have moved our site domain from oldsite.od.ua to newsite.ua (not between subdomains and principal .tld).
Google Analytics continues to collect the same GA property and views, but all GA Client IDs changed. I know about cross-domain tracking, but in my case users don't visit the old domain to go to the new one.
Is there a way to transfer old IDs to the new domain?
We don't use the User ID because we don't have any authorization on our site.
That should be possible, while a little tricky.
You need to read the user _ga cookie that exists on the old site and set it for the same browser on the new site
This is only possible through a special redirect, here is a sample flow:
Accessing to newsite.ua would include in the source of every page of the news site a reference to a resource like an image on https://oldsite.od.ua/special/ga.png
That call is a pretext to allow reading the _ga cookie value on https://oldsite.od.ua/ for that browser through HTTP Request Headers
probably something like GA1.3.1218996493.1586263874
The request to ga.png would be handled by a PHP script for example, able to process HTTP Header values and it would do a 302 redirect to
https://newsite.ua/special/ga.png?ccvalue=GA1.3.1218996493.1586263874
This allows to pass the value of the former GA cookie to the new site context. You will be able to access the "_ga" cookie value in PHP with something like
$_COOKIE["_ga"]
The HTTP Response to the call to https://newsite.ua/special/ga.png?ccvalue=GA1.3.1218996493.1586263874 would have an HTTP header like this
Set-Cookie: _ga=GA1.2.1218996493.1586263874; Expires=<date in 13 months>
Thus passing through the value of the parameter as a cookie value. But only if the HTTP request to https://newsite.ua/ doesn't already holds a _ga in the Request Header (that would mean that the browser has already been migrated)
(You'll need to adjust the code to make sure it doesn't go into an infinite loop for example...)
Note that the ".3." at the beginning of the initial cookie value needs to be replaced by ".2." to match the _ga cookie generation rule on the new domain (it is based on the number of dots in the domain name, and allows GA to select the appropriate cookie between a domain and a subdomain) because in your case you move between different domain patterns
This applies to the analytics.js version
The GA debug extension will help you verify that it's taken into account
You should also consider handling user consent regarding tags and so in that migration..

after federated authentication, redirect to originally requested url

We've setup federated security using ThinkTecture server.
When a user wishes to access a particular URL, they get redirected to the Identity Provider Server (IDP), they login, get authenticated.
Then, the IDP server will redirect the user back to the "Redirect URL" specified in the configuration for that Relying Party.
Instead, I want it to be redirected to the originally requested URL.
Is this possible? I've read a little about the wreply parameter, but not sure how I use this and intercept the authentication levels calls on the original web server, before the redirect.
Update
I've realised that my problem is due to my url containing a hash, e.g. http://domain.com/#customer/123 and nothing after the hash is passed into the redirect url within WIF. See my answer below for more details.
It's up to your app to remember context info like this in the wctx param. If you're using WIF in the RP then this should be done automatically.
I figured out what was happening. I am using WIF and as Brock's answer suggested it should be doing everything itself...and it was.
Normally if you request a url like: http://domain.com/page and the 'Redirect To'/ReplyTo setting in ThinkTecture is just http://domain.com/.
Then when WIF calls out to the STS, it takes the path of the requested domain, in this case /path and adds it to the &ru param within the &wctx param. The &wctx param will look like this: rm=0&id=passive&ru=%2fpage.
Then after the STS has authenticated it redirects the user back to the ReplyTo url, http://domain.com with a body parameter of wctx and WIF picks this up and uses the ru param to do another redirect.
The problem is that my requested url was http://domain.com/#page and WIF doesn't include the #page in the ru param. So my ru param was just /, so it kept redirecting to http://domain.com which there was correct (yet incorrect).
Guess I need to set the ru value myself with the full URL... unless there is a better way.

It is possible to 'Set-Cookie's for every request received in Ruby on Rails 3?

I would like to load cookies everytime and everywhere in my website because when my RoR application receives and accepts an "external" HTTP request (ex: REST API), cookies are not loaded (see RFC2109). So their values are inaccessible.
Cookies are accessible only when the HTTP request is made "internally" in my application.
new_cookies = {"Cookie" => "mycookie=1234;myothercookie=4567"}
Net::HTTP.get( URI.parse( http: //app1.website.com/users ), new_cookies)
All browsers will automatically send any cookies you set from your domain, you can check them simply by calling request.cookies from any controller method. It doesn't matter if the request was initiated from within your application (such as a 302 redirect) or not.
I just tried this with Firecookie:
Created a cookie "mycoolcookie" for the domain ".stackoverflow.com"
Went to stackoverflow.com, firebug showed that the cookie was sent in the request header.
Went to meta.stackoverflow.com, firebug showed that the cookie was sent in the request header.
Went to chat.stackoverflow.com, firebug showed that the cookie was sent in the request header.
A cookie is sent automatically by the browser, the server can never request for a cookie to be sent to it.
REST APIs are generally stateless, therefore you should avoid the use of server-side sessions or client-side cookies. If you want to indicate that a user only grabs resources belonging to them, use the Rails nested resources approach, that results in a call like:
http://abc.com/user/user001/books
For all books that belong to user001.
If you are looking to implement security, first you have to use HTTPS instead of HTTP. For the actual implementation you can use Basic Authentication and set the username/password in the request header or you can use something like OAuth which sets up a token for the user that they pass in with each request.

Resources