passing a query string parameter through auth0 to the app - asp.net

I have an ASP.NET + OWIN app. I have auth0 setup using the nuget package they provide. Log In/Out works as expected.
I'm trying to create a kind of invite system. When a record is created in the app's database, I want to send email with a register link containing an invite code that references back to the record. When the user clicks the link, I'd like to get the invite code and create a link in the app's database back to the user. I've tried to set this up by creating a rule that "enriches" the user's profile with invite code. Most of the time, the code isn't part of the returned user identity though. Every once in awhile it will work, but not often. I can't explain why sometimes it works and sometimes it doesn't.
Any insight would be a big help.

Related

How to create a Magic Link with Firebase to login a user instantly every time he use it?

What I want
I have a list of people with all their personal information (name, first name, date of birth, email, etc.). I created an account for each of these people using their email/phone + a password I generated for them.
I want to send to each of these people an email/SMS with a link allowing them, once clicked :
to be directly connected on our website, without having to type a password or using a third party as Google/Facebook/etc.
and I want the link not to expire after the first use. The user must be able to click on it several times and be connected to our website each time.
What I tried
This is what I tried so far, unsuccessfully :
Passwordless Auth with email link: using both backend and frontend. Doesn't fit my needs because the signin link works only once by design.
Create a custom token with Firebase: as I understood, the token will expire 3600 seconds after creation, which is not useful for me.
Implement anonymous auth: it still need the user to type email+password at some point if you want to convert the anonymous account to a permanent account (because I don't want to use Google/Facebook/etc auth). Plus, it will need consequent changes in all my website code to work.
At this point I realized that Firebase doesn't have a solution that fits my needs. I started to fiddled around as best I could.
The idea
It works as the following:
First I create an account for the user in Firebase + a unique document in a collection in Firestore. That document contains 3 fields: magic_token, email, password.
Then, I create a link to our website with a unique token as a parameter in it. I store the token as magic_token in the document I described above. I send the link to the user.
The user clicks on the link, get redirected to my website. In the front, I detect the presence of the token in the parameters of the URL, I retrieve the document in Firestore with the corresponding token.
Using the email and password stored in this document I call: signInWithEmailAndPassword() to login the user.
PROS:
it fits my needs.
it is easy to implement
CONS:
the user password is visible in Firestore.
it's not very secure.
The question
Is there a proper way to implement a Magic Link that fit my needs? If not, how can I improve my own custom token authentication ?

Meteor Restivus: keep user logged in if he goes to the main website

I have a Chrome extension that communicates with my Meteor app through a REST API created with the Restivus package.
The user authenticates to the REST API and then uses authenticated tokens to make any further requests.
So far, everything works fine, as long as he stays within the extension. However, from the chrome extension, I'd like to redirect the user to his profile page on my main website. When that happens, he's no longer authenticated, and must re-sign-in to access the profile page.
I figure this is because the REST API session and the webpage session are two completely different sessions on the server (even though both the API and the webpage run from the same server). My question is, is there a way to maintain the user's logged-in state as he moves from the extension to the main website?
I figure there are a few options:
I'm using the standard meteor accounts package. Is there a way to push whatever standard cookie / data that the accounts package uses, to the user's browser, so that when he goes to the website, he'll be considered logged in?
Push a custom cookie to the user, which I then check for and log him in when he first comes to the website. However, I don't know how to push a cookie through a REST API or generate one in the Chrome extension
Use DDP to communicate with the second session and transfer the login credentials.
I don't know if these are the best options (or even how to implement them if they are...). Has anyone figured out a way to do this already? Thanks!
I would suggest you to develop your own flow of authentification using a token as an URL parameter. You should achieve a similar experience that slack provides with magic authentification links
The idea is to generate a token and add it to the Meteor.users collection for the user logged in your chrome extension.
Then, redirect your user to an url with the token as a parameter. The app checks which user is linked with this token and log him in.
You can get inspiration on what is done in the account package to handle enrollment and reset links, or in the passwordless package

Google OAuth Always Showing Consent Screen

I'm building an installed application that will have features requiring the Google Drive REST API using Qt and C++. I understand Qt is now releasing new libraries to support OAuth flows but let's assume I'm a student and learning to use OAuth at this layer is a requirement for this project.
In my application, I have a working OAuth flow for installed applications that ends with an Access Token and Refresh Token being stored using QSettings (I'm open to input on whether this is a disastrously bad idea too). The application requires no authentication/login for its own sake/data, but it does need authentication to Google for calling API's using an Access Token. This application has no associated web backend being hosted; its simple and should be deployable completely locally (I've written and included a simple TCP server that will receive the authorization redirect_uri and will run and close when called from within the application).
As such, I'm curious about the best way to make sure that, when a user opens my application and wants to use the Google Drive features, they are appropriately authenticated on Google's end. Say, if I maintain an access token in the registry, and this access token is granted per-user/per-application basis (right?), then how can I make sure only the user the token belongs to is able to make calls to the API with it?
Here's my understanding and approach; feel free to correct me or educate me if I've got the wrong interpretation.
If an Access Token is found, perform the following:
Open a browser page to a Google login domain and have the user authenticate there (this could prohibit a user from being able to use a cached login session that would have access to a token they otherwise shouldn't have access to)
If user has correctly authenticated with a Google account, return control to the application and make a test call to an API using the stored token.
If the call fails (responds with an invalid_credentials) I should be able to be sure its because the access token has expired and the application will go through the flow to renew an Access Token from a Refresh Token.
If no Access Token is initially found:
Start a normal OAuth installed application flow
Get the tokens and store them so that when the user opens the application next time the former procedure is used
My issue then is the first two steps if the Access Token is found. Nominally this could be done by the typical OAuth flow but it appears that when using a localhost as the redirect uri, Google will always prompt for consent, regardless of settings for prompt and access_type authorization query parameters.
What can be done to accomplish these first two steps in a way that my application can control (i.e. not a solution that relies on a backend server being hosted somewhere)?
If this question is too open-ended for SO requirements I can make some more restrictions/assumptions to limit the problem domain but I'd rather not do that yet in case I unknowingly rope off a good viable solution.
Thanks for reading! Sorry if its a verbose; I wanted to ensure my problem domain was fully fleshed out!
If you are using an installed application, I wouldn't recommend using or storing refresh tokens. Storing refresh tokens on the client side means that if an intruder gains access to the client's application, they have infinite access to the user's application without ever having to enter the user's credentials. If you do insist on having a refresh token, ensure you follow the Google's installed app flow, with the code_verifier parameter included in your requests.
If the access token is found, you should try to verify it, and if verified then use it at the google api, otherwise force the user to login again (or refresh it if you chose to still use refresh tokens).
If no access token is found, your flow sounds fine.
A few notes on loggin in with Google:
Google will only return a refresh token if you specify access_type=offline in your auth request.
Google will only return a refresh token on the user's first authorization request, unless you always specify prompt=consent in your query params.
In my experience, when leaving out the prompt query param, the user is not prompted for their consent again. If they are logged in to google, you will get a new access token, but no refresh token, unless you have prompt=consent.
I think the idea is you use prompt=consent if you have no record of the user ever using your application. Otherwise if they have used it before, you may prefer to use prompt=select_account to allow the user to select which account he wants to use in case he has more then one, or you can just use prompt=none.
This is just my understanding of it all.
My approach I ended up using was just to deploy with an SQLite db that will be stored in the AppData roaming directory. The db schema includes a field for the user's Name (from the OpenID IDToken field if it exists), the user's picture URL (again from IDToken if it exists), the refresh and access token strings (will be stored as encrypted strings when I get around to it), the user's UID/sub string, and a field for a user name and password.
These latter two fields are authentication fields for within my own application, which, again, I wanted to avoid but it seems impossible to do so. So the user will be prompted to enter a username and password into a form, and these credentials will be checked against the existing SQLite db file mentioned previously.
If they exist and are correct, the user gets logged in and will have access to their respective access and refresh token.
If the user has forgotten their password, they'll be asked for reconsent (going through the installed app flow again), and whatever password they provided during initial login will be used as the reset password. It is considered, for my purposes, that logging into Google for the installed app flow is proof enough that the user account belongs to them and they should have authorization to reset the password.
If the user is a new user and doesn't have a record in the local SQLite db file, then they can also click a button to "Create New Account" - which effectively goes through the authorization flow as well but this time a whole new record is posted to the SQLite db with the appropriate fields filled.
There's still more optimization that could be done but at least I am getting closer to the level of security and control of access to Google user accounts that I want.
I'm not marking this as an answer because I feel like this solution is still not desired and that there should be an easier way. So if someone has evidence or experience of providing an equivalent level of authentication control without needing to maintain a local user account database then I would be more than happy to mark such a method as the solution!
Thanks again!

Is there anyway to create playlists on Spotify using a command line tool?

I want to create a playlist through the command line, but I appear to need to use the "Authorization Code Flow" method of authentication to be able to do this. The only way I can think to do that, is with a full web app through the browser, but I just want to make a command line tool without any of that hassle.
Is there a way to deal with this?
You do indeed need to use the Authorization Code Flow. However, that doesn't mean you need to build a web app.
Method 1: Prompt from command line, a la Spotipy
Check out the way Spotipy, a 3rd party Python library implements their authentication: https://github.com/plamere/spotipy. It uses the command line to prompt for authentication, then gets users to copy the URL back. This could be an easy workaround if you don't want to fully implement an authorization flow yourself. I recommend going through their quick start to get an idea of a non- web app implementation.
(They even have an example for "Create a playlist", maybe you can just use and build off that? https://github.com/plamere/spotipy/blob/master/examples/create_playlist.py)
Method 2: Get an access token for your account only
The Authorization Guide states the following:
Accessing your data without showing a login form
I want to interact with the web API and show some data on my website.
I see that the endpoints I need authorization, but I don’t need/want a
login window to pop-up, because I want to grant my own app access to
my own playlists once. Is there any way of doing this?
You basically need an access token and a refresh token issued for your
user account. For obtaining a pair of access token / refresh token you
need to follow the Authorization Code Flow (if you need a certain
scope to be approved) or Client Credentials (if you just need to sign
your request, like when fetching a certain playlist). Once you obtain
them, you can use your access token and refresh it when it expires
without having to show any login form.
So, if you only need access for your own account, grab any of the simple tutorials from the internet, follow it, and get an access token. You can then use that access token to make calls.

Connecting to multiple social logins within HWIOauthBundle

I'm trying to arrange being able to login with a social network (initially LinkedIn, but it could be any other, or self-generated from FosUserBundle), and then adding new connections to the same user, via Twitter, FB, Github, etc.
The difficulty is connecting the multiple account connections within FosUser and the HWIOauthBundles. In order to collect as much data as I can, and be able to easily add additional connections to services, I'd really like to have each new connection as a one-to-many record. IE: The initial login with LinkedIn creates a FosUser record, and a new row in a 'socialLogin' table, the next (say login with Twitter) adds a new row to the 'socialLogin' table, that refers back to the fosUser.id.
How can I use the currently logged in (Fos)user as part of the new record that HWIOauth would generate? The end result would be, being able to login with any known user to get into the same account.
The solution is actually easy. First check out Symfony2: How to login using OAuth (HWIOAuthBundle) + custom roles (by default and loaded from DB) which is a great how-to for HwiOAuthBundle, and then scroll down and carefully look at public function loadUserByOAuthUserResponse(){ ... } section.
From there, your workflow will be checking the provider name from the response object. And then based on the provider name, you can update your user (use email for searching). However, with twitter you may have problem because twitter doesn't supply user email. So you need to ask your user for that email address and after you get that, you may need to merge current user account (for twitter based reg, consider it as a temporary a/c) with previous user account with this email.
Otherwise, if your user is already logged in using form/other-social-login (before connecting with twitter) you can add his twitter details once he connects with it. But you need to store user's currently logged in details in session (so that you can fetch it after user comes back with twitter token)
Hope it helps
First step would be to create the relation between the user entity and the social_data table and the rest is all about overriding the custom user provider FOSUBUserProvider.php, which I believe you already have started doing as you have FOSUserBundle and HWIOAuthBundle working together.
I will make some edits with actual code later, but I had to answer this to get you on the track until then.

Resources