How to implement NodeJS OAuth2 for an Angular App? - angularjs

I'm trying to to implement the Resource Owner Password flow with a NodeJS API to authenticate my frontend Angular app.
I'm having problems how to implement how the user sends his credentials (username and password) to the API. The flow I know I'm used to send this body variables:
Request body:
grant_type: password
username: myusername
password: mypassword
client_id: frontendApp
Obs: I don't send the client_secret because It is not important, because It's an Angular app, so eveyone can see, but I created a seed client that represent my frontend client. I also created a flag that only this client (frontendApp) can authenticate without client_secret.
When I come to NodeJS I've been reading some tutorials about how to implement this flow in my API, and I notice that my knowledge of how the authentication flow must ocurs maybe is not a pattern.
I pick these tools to start building the security of the API: passport.js and oauth2orize.
According to the tutorials I do need to protect the token endpoint. I didn't catch the idea of why, because the user will access It to just authenticate, with the grant_type: password or grant_type: refresh_token, so he'll have to send me credentials like username and password in the first case or the refresh token in the second, so why do I need to use passport.js with basic and client password strategy?
Talking about Basic and Client Password strategy... Again according to the tutorials I should implement both, because the Basic strategy authenticates by header and the Client Passport strategy by body content. Here I see some ugly things.
Like I mentioned, I don't see reasons to protect the token endpoint, maybe I'm wrong, maybe exists some security problem that I didn't notice.
Another thing is because the Basic strategy and Client Password have different contexts, the first receive username and password and the second client_id and client_secret. When I want to get access and refresh token for the first time I must send all these things:
Request body:
grant_type: password
username: myusername
password: mypassword
client_id: frontendApp
client_secret: clientsecret
(or with the authentication in the header)
I wouldn't like to send the client_secret, at really nor client_id, but the client password strategy library makes me, and It is something very useless, because everyone can look my frontend code where It is stored, because of It I think It is not necessary to protect the token endpoint.
I'd like to send only the username and password, if the user is sending only username and password I already know that It is an frontend client trying to authenticate. I found an explanation of how Resourse Owner Password should work, and It shows an example of request:
https://oauth.example.com/token?grant_type=password&username=USERNAME&password=PASSWORD&client_id=CLIENT_ID
It shows something like my older ASP.NET app, using username, password and client_id.
Does someone know if I should care about It or I can build It my-like mode, because the NodeJS implementations is not following the way I know.

Related

React + Django send raw password in HTTP request, security discussion

I am new to Django and I am working on the user authentication part. I used the Django provided User model, and use auth() and login() method when the user login.
I have a question about the password security and hope have some discussion here.
When the auth() function hashed the raw password and then compares the username and the hashed password. That means the front end needs to send the password in raw data. (Otherwise, it will be hashed twice).
Is it not safe to send the password in raw data? If I want to hash the password in the frontend then send the request to Django, what can I do in this case?
It's OK if you pass password in post request
But for more security, you can encrypt data ...

How to get data from Microsoft Bing Ads API

I'm trying to get Bing ads spends from my firm. According to the Microsoft documentation, I understood that it's mandatory to use Microsoft Azure portal, get developer_token, client_id, tenant_id, client_secret, and access/refresh token to download the csv files with the data I want.
So, this is what I did:
I've received an invitation from my firm to Microsoft advertising onto this email adress:
abc#myfirm.fr, and I've generated my developer token.
With this email address, I've created a web application onto Microsoft Azure portal, which allow all king of users. Getting client_id, tenant_id, and generated a client_secret.
The redirect URL that I have chosen is http://localhost (according to the documentation but not sure this is the good URL to choose).
With Postman, I have tried with this endpoint:
https://login.microsoftonline.com/common/oauth2/v2.0/authorize
and the params (previously obtained) needed for the OAuth 2.0 authentication to get my access token. Without success.
The issue is here.
When I request the access token, a new browser window opens, and asks for an email address on which to authenticate. I'm using my email address abc#myfirm.fr and I received authentication completed onto Postman but into the response body I have access_token: invalid.
The role of my account is super admin.
So I'm trying to authenticate with a professional Microsoft Azure Account and this time I received into the browser Invalid redirect url.
I have also tried to start all over again with different email address, like my personal email address, or with the email address of the creator of the Microsoft Advertising account, and I get the error contact your system Admin into the browser.
I have also tried with the Python SDK project given in the documentation, with the error message.
I must have forgotten or misunderstood something.
Should we use the same email address (or same account) on Microsoft Advertising, on Microsoft Azure, and when obtaining the access token?
Do you have to pay and take an Azure subscription? (Already done but without success)
Thanks in advance, sorry for my English.
EDIT:
Thank for ypur reply. The full request is: https://login.microsoftonline.com/common/oauth2/v2.0/authorize with the following params:
-type: OAuth 2.0
-Header Prefix: Bearer
-Grant Type: Authorization Code
-Callback URL: https://localhost
-Auth URL: https://login.microsoftonline.com/{my-tenant_id}/oauth2/v2.0/authorize
-Access Token URL: https://login.microsoftonline.com/{my-tenant_id}/oauth2/v2.0/token
-my client id
-my client secret
-scope: https://ads.microsoft.com/ads.manage OR also testing with https://graph.microsoft.com/User.Read
-State: None
-Client authentication: send client credentials in body
Give me an access_token but when I click on use token and send the request, I'm not getting an refresh token
Once a user provides consent, you can get an access token and act on behalf of the user.
So when the browser session starts, you should enter your Microsoft Advertising credentials.
Remember to set scope=https://ads.microsoft.com/ads.manage in the request for acquiring the authorization code.
If you prefer to automate this process, you can refer to this script and steps to obtain an access token.

IdentityServer4: Using refresh_token to get a new access_token when clients doesn't know the client_secret

Firstly: I can successfully make calls to
http://localhost:7791/connect/token POST
grant_type=refresh_token
&refresh_token={refresh_token}
&client_id=resource-owner-client
&client_secret=secret
and this returns a new access_token, refresh_token, expires_in, and token_type.
However, I want to do it without a client_secret.
In my case my clients are remote applications that have been issued a starting access_token, refresh_token, etc.
using this call.
http://localhost:7791/connect/token POST
grant_type=password
&scope=arbitrary offline_access
&client_id=resource-owner-client
&client_secret=secret&username=rat&password=poison
The initial call is trusted and the secrets know, but downstream usage of the refresh_token should not require the client_secret.
How can I configure this or where would I have to code my own abstraction to make things work this way?
Not out of the box.
You could implement that using an extension grant.
https://identityserver4.readthedocs.io/en/release/topics/extension_grants.html

How to interact with back-end after successful auth with OAuth on front-end?

I want to build small application. There will be some users. I don't want to make my own user system. I want to integrate my application with oauth/oauth2.0.
There is no problem in integration of my front-end application and oauth 2.0. There are so many helpful articles, how to do this, even on stackoverflow.com. For example this post is very helpful.
But. What should I do after successful authorization on front-end? Of course, I can just have flag on client, which says "okay, mate, user is authenticated", but how I should interact with my backend now? I can not just make some requests. Back-end - some application, which provides API functions. EVERYONE can access this api.
So, I need some auth system anyway between my FE and BE. How this system should work?
ps I have some problems with English and may be I can not just correctly 'ask google' about it. Can you provide correct question, please :) or at least give some articles about my question.
UPD
I am looking for concept. I don't want to find some solution for my current problem. I don't think it is matters which FE and BE I use (anyway I will
provide information about it below)
FE and BE will use JSON for communication. FE will make requests, BE will send JSON responses. My application will have this structure (probably):
Frontend - probably AngularJS
Backend - probably Laravel (laravel will implement logic, also there is database in structure)
Maybe "service provider" like google.com, vk.com, twitter.com etc remembers state of user? And after successful auth on FE, I can just ask about user state from BE?
We have 3 main security concerns when creating an API.
Authentication: An identify provider like Google is only a partial solution. Because you don't want to prompt the user to login / confirm their identity for each API request, you must implement authentication for subsequent requests yourself. You must store, accessible to backend:
A user's ID. (taken from the identity provider, for example: email)
A user token. (A temporary token that you generate, and can verify from the API code)
Authorization: Your backend must implement rules based on the user ID (that's your own business).
Transport security: HTTPS and expiring cookies are secure and not replayable by others. (HTTPS is encrypting traffic, so defeats man-in-the-middle attacks, and expiring cookies defeats replay attacks later in time)
So your API / backend has a lookup table of emails to random strings. Now, you don't have to expose the user's ID. The token is meaningless and temporary.
Here's how the flow works, in this system:
User-Agent IdentityProvider (Google/Twitter) Front-End Back-End
|-----------------"https://your.app.com"---------->|
|---cookies-->|
your backend knows the user or not.
if backend recognizes cookie,
user is authenticated and can use your API
ELSE:
if the user is unknown:
|<--"unknown"-|
|<----"your/login.js"----------+
"Do you Authorize this app?"
|<------------------+
|--------"yes"----->|
+----------auth token--------->|
|<---------/your/moreinfo.js---|
|-------access_token ---------->|
1. verify access token
2. save new user info, or update existing user
3. generate expiring, random string as your own API token
+----------->|
|<-------------- set cookie: your API token --------------------|
NOW, the user can directly use your API:
|--------------- some API request, with cookie ---------------->|
|<-------------- some reply, depends on your logic, rules ------|
EDIT
Based on discussion - adding that the backend can authenticate a user by verifying the access token with the identity provider:
For example, Google exposes this endpoint to check a token XYZ123:
https://www.googleapis.com/oauth2/v3/tokeninfo?id_token=XYZ123
I read through all the answers very carefully, and more than half the people who responded are missing the question completely. OP is asking for the INITIAL connection between FE & BE, after the OAuth token has been issued by the Service Provider.
How does your backend know that the OAuth token is valid? Well keep in mind that your BE can send a request to the Service Provider & confirm the validity of the OAuth token, which was first received by your FE. This OAuth key can be decrypted by the Service Provider only because only they have the secret key. Once they decrypt the key, they usually will respond with information such as username, email and such.
In summary:
Your FE receives OAuth token from Service Provider after user gives authorization. FE passes OAuth token to BE. BE sends OAuth token to Service Provider to validate the OAuth token. Service Provider responds to BE with username/email information. You can then use the username/email to create an account.
Then after your BE creates the account, your BE should generate its own implementation of an OAuth token. Then you send your FE this OAuth token, and on every request, your FE would send this token in the header to your BE. Since only your BE has the secret key to validate this token, your application will be very safe. You could even refresh your BE's OAuth token on every request, giving your FE a new key each time. In case someone steals the OAuth token from your FE, that token would be quickly invalidated, since your BE would have already created a new OAuth token for your FE.
There's more info on how your BE can validate the OAuth token. How to validate an OAuth 2.0 access token for a resource server?
let's use OAuth concept to begin,FE here is Client , BE here is Resource Server.
Since your client already authorized, Authorization server should grant
Access token to the client.
Client make request to the resource server with the Access token
Resource server validate the Access token, if valid, handle the request.
You may ask, what is the Access token, Access token was issued by authorization server, grant to client, and recognized by resource server.
Access token is a string indicate the authorization information(e.g. user info, permission scope, expires time...).
Access token may encrypted for security, and you should make sure resource server can decrypt it.
for more details, please read OAuth2.0 specification https://www.rfc-editor.org/rfc/rfc6749.
Well you don'y need User-System on your Front End side.
The front end is just a way to interact with your server and ask for token by valid user and password.
Your server supposed to manage users and the permissions.
User login scenario
User asking for token by entering his username and password.
The server-API accept the request because it's anonymous method (everyone can call this method without care if he's logged in or not.
The server check the DB (Or some storage) and compare the user details to the details he has.
In case that the details matches, the server will return token to the user.
From now, the user should set this token with any request so the server will recognize the user.
The token actually hold the user roles, timestamp, etc...
When the user request for data by API, it fetch the user token from the header, and check if the user is allowed to access that method.
That's how it works in generally.
I based on .NET in my answer. But the most of the BE libaries works like that.
As am doing a project for SSO and based on my understanding to your question, I can suggest that you create an end-point in your back-end to generate sessions, once the client -frontend- has successfully been authorized by the account owner, and got the user information from the provider, you post that information to the back-end endpoint, the back-end endpoint generates a session and stores that information, and send back the session ID -frequently named jSessionId- with a cookie back to the client -frontend- so the browser can save it for you and every request after that to the back-end considered an authenticated user.
to logout, simply create another endpoint in the back-end to accepts a session ID so the back-end can remove it.
I hope this be helpful for you.
You need to store the token in the state of your app and then pass it to the backend with each request. Passing to backend can be done in headers, cookies or as params - depends on how backend is implemented.
Follow the code to see a good example of all the pieces in action (not my code)
This example sets the Authorization: Bearer TOKEN header
https://github.com/cornflourblue/angular-registration-login-example

Angularjs + RESTful API exposed registration

We started developing a RESTful app for registrations, signing in and posting some simple stuff. We're using AngularJS for the frontend which handles users registering, logging in, signing out etc.
The backend accepts the following paths:
POST /register (params: email, password)
POST /login (params: email, password)
POST /logout
After the user logs in, a JSON token is generated. This token is then used for each and every subsequent request - like GET /items or DELETE /items/5. Without that token every request is denied with a 401. This part works perfectly because I can use the API in a browser through AngularJS, in an iPhone/Android App and even for 3rd parties.
The only publicly exposed paths are /register and /login. While doing a POST on /login from the outside is natural and makes sense I'm worried that anyone can do a POST /register from the outside and just flood the server with registrations.
I found somebody doing a similar app, I just launched POSTMAN and did a POST query on /signup which worked.
http://www.mircozeiss.com/github-like-signup-form-with-angularjs-and-bootstrap-v3/
I can't help but think that this is not a best practice scenario when it comes to registering users. Registering users with Google+ or Facebook is not an optimal solution. Any ideas on how to prevent bogus/flood registrations from outside? Is there a way to secure this part of the API (/register)? Should I just rate limit the number of requests?
If it's free for all app, better X-Rate-Limit the register api endpoint like Github and all, otherwise just process register requests if it has a auth token with admin privileges (allowed to create credentials for other app-user).
The backend accepts the following paths:
POST /register (params: email, password)
POST /login (params: email,
password)
POST /logout
First of all, this is not a REST API, because it violates the stateless constraint of REST. Use encrypted connection and send the username and password in the HTTP basic auth header with every request. That is stateless.
Any ideas on how to prevent bogus/flood registrations from outside? Is
there a way to secure this part of the API (/register)? Should I just
rate limit the number of requests?
This does not depend on REST. You can do just the same with every web application which allows registration. Typical solutions to use a captcha or send a verification link in email. You can limit the rate, but that is not an effective solution.

Resources