Getting a 401 response on couchdb authentication - authentication

I've spent the last day or two pulling my hair out over this, so I thought I'd share the answer.
Problem: When trying to get an authentication cookie from the client side (using some http library or another), you get a 401 Unauthorised response. Even though you know the username and password are correct and you're doing it exactly how it's done in all the examples. Well my friend, your issue is that you expect things to make sense.

Turns out that if you have the require_valid_user set to true in the couch db config, and then don't include those credentials with an authentication request (even if the credentials you're authenticating are valid!) couch will reject it out of hand. So you've two options really,
Keep require_valid_user true and do your authentication on your own server where you can wack in the admin username and password as a part of the url (like so url = http://admin:password#url:5984). And then authenticate your credentials and pass back the ensuing cookie you get from that. (Make sure in subsequent requests straight from the client to the db you include withCredentials:true, so the browser sends the cookie with the request).
Say screw it and don't require a valid user with each request, and instead authenticate on the design doc and database security level only. I can't vouch for how secure this is, as I haven't done it.

Related

How not to share authentication cookie between different webapps with the same auth server

This question is the opposite that what most questions/tutorial are talking about.
Lets assume we have 2 SPA under the same domain. For example spa1.company.com and spa2.company.com. They are both authenticate against the same api api.company.com
The server set a cookie httponly, secure, samesite=strict with the domain api.company.com. The cookie is only needed by the authenticated function api.company.com/authenticate (so the path of the cookie is /authenticate)
(as far as I understand, it cannot be set as spa1.company.com becasue then it won't be sent when calling api.copmany.com)
So now the cookie will be sent by both SPA when they call to the authenticate method. What the settings should be in order to have 1 cookie per SPA?
I can do some funny stuff with the path to mitigate it, but I'm sure there are better solutions out there.
Please use this solution with pinch of salt. It works well, but maybe there is a more best practice approach.
Add to the URL an app idnetifier for the clinet. For example:
api.company.com/authenticate/spa1
api.company.com/authenticate/spa2
Then you can set the path of the cookie to include the app identifier and it won't be shared between the clients

Google OAuth2 redirect_url

I'm unclear about how OAuth2 (or at least google's implementation of it) works for server applications as far as redirect_url is concerned.
I'm trying to achieve three use cases:
Case 1:
A user who has never logged in logs in through my web interface using the well-documented tools found in the google identity management API, which produces a token.
My javascript client sends the resulting token along with username (or anything else needed) to the server.
The server uses the token and additional information to make sure the user is authenticated and has access to some resource that is requested, for instance basic login.
Case 2:
A user has already logged via web page and their token is available as a cookie that has not expired, and the initial page forwards that to the same token checking mechanism as above.
The server uses the token to validate their session.
Case 3:
A user is accessing my server from an app (like Unity or some other compiled Qt application or even on a command line) and is prompted for credentials because no token can/should exist when cookies aren't a thing in this context.
If their credentials are no good, the application says so, and asks for new ones.
If the credentials are good, a token is generated but is probably not used except if the token needs to be refreshed at some time interval, because we assume that re-running the app or command line is effectively a new session.
None one of these cases requires my server to use the redirect_url (except maybe the case of #2 where the token is expired), because:
Case 1, the user would have been unable to pass a token in the first place if they can't log in, and would have been redirected before that.
Case 2, the server accepts the token and doesn't redirect, or rejects the token and only then may redirect them back to the initial state of Case 1, but the server already wants to redirect them because the token is invalid, so I don't need/want the redirect_url from oauth.
Case 3, we are assuming there is no browser and don't care about redirect_url in any case no matter what.
As my code works now, using: https://developers.google.com/identity/protocols/oauth2/web-server there is always this redirect_url field which I don't know what to do with, and when I execute REST commands I'm getting raw html back which includes self-submitting javascript instead of useful headers.
I can see a case for exposing some URL on my server to validate an oauth2 session/token from google during authentication, for instance, but that would be a validation url, not a redirect_url, because the user/server doesn't "go" to that url at that point in the process.
So, I don't know what to do with redirect_url because when I leave it out, things don't seem to work.
There's a lot going on in this question, so I don't really know the type of answer you're looking for. I wrote our code for authenticating our Qt app with Google SSO, and wrote the linked post discussing the problems we faced.
One thing I found confusing in the documentation and provided examples is that when defining an app in the Google console, if your client is a desktop one, there's no field for redirection URLs. Instead, the client specifies it when initiating the authentication flow, and then it's expected to open a transient server that listens for the return connection from the Google side. There's no point declaring it on the Google console because it cannot be validated unless the client app is running at the moment, and even then, it's typically a hardcoded URL like http://127.0.0.1:1234/ as you would expect.

fetch httponly cookie persistence through app closures

I am currently using httponly cookie based authentication to authenticate users through a website. On top of this I am creating a react native app which also has to authenticate users, ideally through the same endpoint. At this point users are able to log in through the app and the cookie is correctly send on each subsequent request using credentials: 'include' (fetch). However, if the app is restarted, the cookie does not persist.
So far my searching has led me to the following possible workarounds:
Manage cookies manually by extracting the cookie through something like webview or react-native-cookies, saving the cookie to storage and manually adding it to each subsequent request.
Implement a new endpoint that returns a token and have two authentication flows, one for the website and one for the app.
Have anyone been in a similar situation? Can you point me in the right direction, so not to over complicate my code base and ensure that I am not vulnerable to XSS or other token/cookie theft.
Thanks in advance.
To be honest I never implemented cookie based authentication in react native. How do you handle cookies now ? Basically the flow should be like this:
You authenticate with username and password.
Server will respond with a header "Set-Cookie: sessionIdExample=1234"
Next time when you make a request you should also send that cookie, meaning you have to set a header "Cookie: sessionIdExample=1234"
From your question I guess you don't manually set that cookie, so most probably the http client is doing this for you. Now when you close the app that cookie value is lost as you said. Notice that switching to a token based authentication won't help with this. So what should you do:
Login with username and password.
When you receive that session cookie persist it. You can check async-storage or the more secure react-native-keychain for persisting data.
For the following requests set the session cookie manually.
When you close the app and then open it again, check in your async-storage or keychain if you already have a cookie saved there. If so, set that cookie and everything should work fine.

OAuth2 Authorization Code in Cookie, good or bad?

I can not seem to find a SIMPLE answer to the question on how to persist OAuth2 authentication... Let's take Google+ OAuth2 API as an example.
User goes to page
User is not authenticated, and gets redirected to authentication page where he logs in
User logs in successfully and authorises my app
User gets redirect to specified (by me) URI with Authorisation Code
I use authorisation code to obtain a token in order to submit queries in the name of the user
All is good and well. My question is: how do you SECURELY know at step 2 that the user visiting the page is already logged in, without having to go through the whole process of redirecting him to all these pages.
I assume storing the Authorisation Code retrieved at step 4 in a cookie is not an option.
All of this will happen in a server-side (Go - if that matters) application.
Any help is much appreciated... I need a simple solution.
Thank you!
use server-side sessions to store any authentication state or even access tokens if you need them.
one solution is to use a database for session store (an encrypted cookie holds the session id)
and another is to use cookie sessions (encrypted cookies that hold the session data).
using encrypted cookies that only the server is able to decrypt should be safe enough.

Google+ Sign-In button deployed, can a page restrict access without a server $_SESSION?

Say the page where user can update his own profile: profile_update.php?id=1234567...(user's Google id).
Question:
How can I restrict access with the returned authResult or me? (I mean which item in the object will help that, not how to get these item out).
or Do I still need to build a server side $_SESSION for that?
You could do some validation on the client side using the auth result, but you'd also want to verify that the request you get on the server side is from who you think it is from to prevent cross-site request forgery attacks. So you'd need something that validate that the POST that update the profile came from an authenticated user, not just that the POST data was in the correct format. So typically, your form will send a specific code (a CSRF token) and that same token must be present in the user's cookies (or a server side session token, which in PHP can be accessed via $_SESSION).