Using OAuth2 for internal tool - security

I want to use OAuth2 for an internal tool in our company to log into the tool with Keycloak. Right now my workflow looks like this:
The user is sent to the client application where he logs in
The client application redirects the user with the authorization code
I extract the authorization code and try to get the access token
a) If getting the access token is successful the user can use the app
b) If getting the access token is unsuccessful we go back to 1.
Note that I don't need any data from Keycloak, I just want to use it for authorization. Also I don't need roles with different privileges, all users are allowed to use the full application.
I have no training in security so please tell me how to improve this process.
Also what would I have to change such that the user can refresh the page without having to login all the time?

Related

NodeJS application to use quickbooks Oauth2.0 and stay log in

I was able to implement a NodeJS application to sign in with my quickbooks developer account using OAuth2.0.I have the client key and the secret key and I am able to get the access token by signing in to quickbooks with their pop up and it redirects me to my application, and then the user is able to send invoices or get data from this quickbooks account.
However, I want the user not to have to sign in to quickbooks in order for it to send invoices or any other operation on quickbooks. I want to be able to write the functionality the application is allow to perform on the QuickbooksAPI by automatically signing in into quickbooks. How can I achieve this?
To word this differently, I want the NodeJS server to log in into quickbooks automatically if application user has the roles or permission to do a quickbooks action, such as creating and invoice or retrieve information. The application should grant itself permission to the OAuth2.0. How do I do this? with a JWT token? Not sure
A bit of background: I was able to accomplish Oauth2.0 authentication by using node-quickbooks by mcohen module.
Thank you in advance
The application should grant itself permission to the OAuth2.0. How do I do this?
You can't.
But you may also be misunderstanding how OAuth is supposed to work.
You need to have the user go through the OAuth process ONCE. EXACTLY once. Never more than once.
Once you have them go through that process once, you get back an access token and a refresh token.
You can then use those tokens to get updated tokens whenever you want (e.g. refresh your access/refresh token programatically, without any user interaction at all). See the docs:
https://developer.intuit.com/app/developer/qbo/docs/develop/authentication-and-authorization/oauth-2.0#refresh-the-token
So, have the user go through OAuth once. Then store the tokens in your app. Refresh the tokens via the refresh token API. The user just has to auth exactly once, and then everything else you can do automatically forever going forward.

Google API Authentication Tasks API

I want to create a Lambda function that uses the Google Tasks API to add tasks every evening at a certain time.
I am unsure of how to authenticate with my account and be able to store access tokens / credentials securely in my lambda environment variables.
As I understand it since my lambda is making a request on behalf of a user (which will always be me in this case) it seems like everything in the docs points to needing to use OAuth2.0 to authenticate which makes sense since you'd want the user's permission to make changes in their account. However since I only want to do so on my account, I wanted to know if there was a way to simply authorize my account without doing a OAuth flow which I don't believe is possible from a lambda since I won't be responding to it every time it runs.
How would I authenticate my application so I can make calls to the tasks API and be authenticated against my account?
This is surprisingly more work than I'd imagined and unfortunately google doesn't generate developer tokens which would have solved a lot of this problem.
Authorization & Consent
There are no immediate ways of authorizing your account for the app that you've created without going through the consent flow. Some cloud service providers generate a developer token for testing your app with your credentials - but google doesn't seem to have this functionality. Not for the Tasks API anyways. AdWords API talks about a developer token but I'm not sure if it's the same concept.
You won't have to re-authorize once you've given consent. This general principal applies to other OAuth using parties, unless the level of consent changes (example: the app starts asking for write permissions in addition to previously consented read) you won't get re-prompted. If permission levels change, you'll get re-prompted.
Now - the second part - how do you make one?
Google explains it in detail here - but I'll further simplify because you don't need to setup a web-server for your case, you're only doing this for yourself.
Our goal is to only to get you the initial refresh token. Once you've retrieved the refresh token, you can use that from your Lambda to retrieve a new access + refresh token whenever you're accessing the tasks API. You just need to keep the refresh token stored somewhere, so you can continuously keep on accessing the tasks API. You're just looking to get the access + refresh token.
Head over to https://console.developers.google.com and create a new application.
After the creation, click 'Enable APIs and Services' and look for Tasks API.
Proceed with creating the credentials and make sure you select you'll be calling this API from a Web Server. Selecting Browser (JavaScript) would only give you an access token and not a refresh token, because they would trust you to store the refresh token on your server, but not on a browser. An access token is time-limited to (conventionally) 60 minutes.
You should also select the User Data / Information and not the App Data / Information for the types of data you want to access. The app one is generally used for GSuite.
Set your redirect uri to be http://localhost:8080 - This is where you normally would need a web-server but we'll just redirect back to your machine and get the parameter from here. It obviously won't find a web-server but the parameter we want is in the url, we'll just copy it.
Now here comes the authentication part. Google's auth url is: https://accounts.google.com/o/oauth2/v2/auth
We will add parameters to this url
access_type=offline // so your daemon app can access it offline
response_type=code // required if you have access_type=offline
scope=https://www.googleapis.com/auth/tasks // what do you want to access to
redirect_uri=http://localhost:8080 // where would google send the code
client_id=
so the whole thing should look like https://accounts.google.com/o/oauth2/v2/auth?access_type=offline&response_type=code&scope=https://www.googleapis.com/auth/tasks&redirect_uri=http://localhost:8080&client_id=
Go to this URL and you should get prompted for consent.
Consent to it and google should redirect you to http://localhost:8080/?code= We'll need that code. That needs to be sent to google to get an access + refresh token.
Code exchange: Make a post request to Google. You can use PostMan. Again normally all of this would be automatically handled by a webserver (detect code parameter, make post request etc..) - but we just need the refresh token here, so we can stick that into our Lambda app.
POST to:
https://www.googleapis.com/oauth2/v4/token
with parameters:
code=<the code you've retrieved>
client_id=<your_client_id>&
client_secret=<your_client_secret>&
redirect_uri=http://localhost:8080&
grant_type=authorization_code
Google should return you the access token and the refresh token. From this point on you need to save the refresh token into your Lambda app - and if it's running on a scheduled job on every bootup:
Read the refresh token
Call Google for a new refresh token + access token
Save the new refresh token.
Use the access token to access your Tasks API.

Get Spotify Access Token without logging in and without a server-side

I am making an app that returns a music playlist based on a user’s age. The user does not need need to log in to their account; they only need to provide their age. I also have no need for a database, so I decided that I want to make the application front-end only.
In order to make requests to Spotify’s API, I need an access token which I get via client credentials, because the user doesn't need to login using that flow. However, the script I used to get the access token must be run from the server-side, which I discovered here: Access-Control-Allow-Origin denied spotify api.
The alternative solution is to use the implicit grant flow, which will allow the script to be run client-side but will require a user to log in. So, both the client-credentials and implicit grant flow don't solve my problem.
How can my web app get an access token so that I don't need to implement a server-side or have the user log in?
Although the idea is different, I want to do something like this person is doing # http://sixdegreesofkanyewest.com/. No one logs in, yet he is able to get an access token and send api requests on their behalf. And I don't really see why that website would require a database either.
If I do end up having to develop a back-end, then I would be able to use client-credential flow. But, how would my back-end send the access token to my front-end without a DB?
Any help is appreciated. Thank you!
Implicit grant is recommended for javascript based application, who can not keep secrets safe. So you may have to strike out this option.
Having a server page, (hope the credentials kept safe in your server), then server app sending the request for token and rendering the page..
I guess that is what the http://sixdegreesofkanyewest.com/ will be doing.
So your option is server pages application. or an intermediate API call to get the access token for you and continue your application logics

Authentication strategy between my chome extension and server

I'm in the process of building a Google Chrome extension, and have some questions about how to implement security into the application.
I need to access a couple of Google API's so am going to be using OAuth 2.0 for that. So basically from the extension I know which user is logged into the browser.
My extension then needs to get and post data to my (nodejs) API service. I want to ensure that the user requesting data is the same user that is logged into the browser. Is there any way of using the previous Google authentication process to also authenticate communications between the extension and my API? I dont really want the user to have to log in again, to access my API.
I'm sure I'm missing something simple, and I've not been able to find anything that fits this scenario
Follow the OpenID Connect auth flow and you will get an access_token and an id_token. The acess_token you will use to use to make authenticated requests to Google APIs as usual. The id_token will be used as authentication with requests to your server.
When the requests hit your server you will need to validate the token and you can then use the contents of the id_token to identify the user.
User wouldn't have to login on auth process provided if user is already logged in and you are using a web application flow (not chrome.identity APIs) but user would see the consent screen atleast the first time. However you can skip the account selector screen if you already know the email address by providing &login_hint= parameter.

How to add oAuth to authenticate developers, not get users permission

I am currently creating an API (who isn't) however when I look for a way to use oAuth in the ways Facebook and twitter do to authenticate users trying to get data all i find is a way to get users permissions which I do not need, the idea of my implementation of oAuth is to authenticate the developer so when they make an API call the server knows who they are and what to serve them. I haven't tried any oAuth code because I haven't found node module that will help so far, however I can give background. I am using:
Mongoose, to query MongoDB
Express, for the HTTP Server
I do not explicitly want to use oAuth, I simply thought it was a good idea, I am open to any other way of doing things.
I think you should read the OAuth specification and to decide if one of the grant flows suits for your requirements. When user(developer) logs in you grant Access Token to him/her. Now on when user makes request to API the Access Token must be on HTTP request header, extracting that Access Token on back-end service from the request you can identify the user.
It is up to you what kind of information you store to DB from the user when she/he registers to your service. But all that information can be mapped with the Access Token that user gets after succesful login or stored inside the Access Token also.

Resources