Why is MSDN telling me to create a OAuth2.0 client when I just want a barebone test for my API? - node.js

I have a REST API, written with express directly. Nowhere in it do I use session, and authentification is for now done using JWT.
However, I dislike having to handle, save and secure user's credentials, that is when I heard about Azure Active Directory.
Adding passport to my app was easy enought, but that's when trouble started.
First, I had to search what strategy I needed, and all of them seems to require the server to maintain sessions/remember who is logged in, all the while using JWT internally. That seems contradictory, JWT is supposed to remove the need of maintaining session.
Finally, I found this MS example which use the Bearer strategy without session.
After setting it up (changing the config file for the right tenant, client ID, changing the routes for a test app more representative of my API), I tried to use them. The protection work well since I am indeed "Unauthorized". But how do I get a valid token to send?
The MSDN guide that use that quickstart don't mention it at all, just redirecting to the AAD library for Android or iOS, implicitely telling me to develop a test app in another language when I just want a crude tool to test if my test server work at all!
That is especially frustrating since I am pretty sure it is "just" a series of HTTP(S) request on the tenant, and the call to the api with the token attached, but I can't find anything to do just that.
/!\: I know asking for something as vague as "How can I do that" isn't a good question, and this question isn't one. What I am asking is why I couldn't find some tools like POSTMan that implement OAuth and allow to quickly test and debug a OAuth protected API. What are the reason that push MSDN to tell me to write a custom tool myself instead of providing a barebone one?

The code sample you mentioned in the post is using the Azure AD V2.0 endpoint. We can use OAuth 2.0 code grant and client credentials flows to acquire the token from this endpoint.
To compose the OAuth 2.0 request directly you can refer the links below:
v2.0 Protocols - OAuth 2.0 Authorization Code Flow
Azure Active Directory v2.0 and the OAuth 2.0 client credentials flow
In addition, the access tokens issued by the v2.0 endpoint can be consumed only by Microsoft Services. Your apps shouldn't need to perform any validation or inspection of access tokens for any of the currently supported scenarios. You can treat access tokens as completely opaque. They are just strings that your app can pass to Microsoft in HTTP requests(refer here).
If you want to protect the custom web API with Azure AD, you can use the Azure AD v1.0 endpoint.

For getting a valid token to send to your API, you'll need to do an auth request to login.microsoftonline.com and get an access token (in the JWT format). Then you can send this token to your api in the http body: "Bearer ey...".
If you want a full sample with a client app that hits that API sample you tried:
Dashboard w/ all the samples for Azure AD Converged Apps
Simple Windows Desktop App
Angular SPA
Node Web API

Related

Securing Azure App Service API calls without passing user credentials

I have a Xamarin forms mobile application that is accessing my app service up in azure. I want to secure the APIs so that only my client application can access them. The mobile app does it's own user/password authentication/authorization, so I don't need AD or a 3rd party for that. I just want to secure my APIs. All examples I can find seems to assume there is an AD user authenticated and I can pass a token from that. Is there a simple way to use the Azure "expose api" functionality without using an AD user? The mobile app is using REST api calls, so I'm also struggling with how to even pass in a proper authentication token if I can put one together. Thanks in advance.
One way to secure is adding an API Management in front of your API's and require subscription, then only calls with a specific ocp-apim-subscription-key will be accepted. I don't recomment storing the ocp-apim-subscription-key value in your app as anytime you need to change it, a new version of the app will be required. I recommend returning it after a succesful login by your users, this way, you're free to rotate the ocp-apim-subscription-key key when needed.
Since you are trying to validate the client application only and not the end user, you should either look into OAuth 2.0 - which has a more complex implementation since it encompasses both application and end user authentications - or you could set up JWT authentication which is simpler and which purpose is to authenticate either client applications or end users, not both at the same time like OAuth.
After your implement the authentication on your API(s), you send over the generated token(s) over a Authentication header on your Requests.

Server-side authentication using Google accounts in a Chrome extension

I have a Web application that currently uses OAuth2 to authenticate users using their Google accounts. The flow is quite standard: the user logs in to Google, the web app gets a callback, retrieves the user identity and stores it in the session.
Now I need to create an accompanying Chrome extension. This extension needs to access the web app underneath, so it needs to authenticate against this app. I configured my extension using the official documentation, but during experiments, I realized this is not what I need. Since it uses the OAuth2 implicit flow, it doesn't return a token that could be validated on the server side. This flow is suitable only for using Google APIs on the client side, which is not my use case. This documentation (and pretty much everything else I found on the Web) focuses on two possible cases:
We want to access Google APIs on the extension side (chrome.identity.getAuthToken()).
We want to authenticate using an alternative OAuth2 service (chrome.identity.launchWebAuthFlow()).
However, in my case, I'd like to authenticate users using Google accounts, but process the token on the server side of my Web app. I could use option 2 here, but it just doesn't "feel right" to me to create my own "non-Google authentication service" that is just a wrapper over Google authentication service, only to be able to authenticate on the server side.
Is option 2 really the only way to go, or is there any simpler way?
I also saw someone recommending using the tokeninfo endpoint to validate the token, but I find it hard to make sure that this is indeed an "official" and secure way of doing this.
To retrieve an access token that you can use on both parts of your app, the extension and the server, you should request a Google Cross-Client Access Token. This allows you to register your two apps (two client IDs) in a single project and share an access token.
This is described and discussed by Google here:
Docs: Google Identity Platform: Cross-client Identity
Video: Google Drive SDK: Cross-client authorization
The rough steps are:
You will need two clientIds, one for your extension and another for your server app
Add both clientIds to a single project
Retrieve the cross-client access token from your extension
Send it to your server via HTTPS
To do this in Chrome, it looks like you would call chrome.identity.getAuthToken() with a callback function that sends the token to your web app.
The reference says the following on chrome.identity.getAuthToken():
chrome.identity.getAuthToken(object details, function callback)
Gets an OAuth2 access token using the client ID and scopes specified in the oauth2 section of manifest.json.
and that it can take a callback function as specified as:
Called with an OAuth2 access token as specified by the manifest, or undefined if there was an error.
If you specify the callback parameter, it should be a function that looks like this:
function(string token) {...};
Ref: method-getAuthToken

Can two Azure web applications use the same token for authentication?

I've got a SPA application and an associated API from which it gets its data. (Aurelia and Nodejs)
I have recently worked out the Authentication on the SPA so that it uses MSAL to authenticate users against our company's AAD and is able to retrieve a token that the app can then use to access the MS Graph as well.
However, I also want my API to authenticate against the AAD. What I'd like is for the API to be able to accept the token from the SPA client.
While I am able to send the token from the client to the API (Authorization: 'Bearer'...) I'm not sure what to do with it on the server side to then verify with the identity provider that the token is valid.
For the most part, I don't want the API to have UI concerns (i.e. an authentication/login screen). It should simply reject any requests that do not carry the correct token.
I hope to eventually have both client and server apps being hosted as App Services on Azure, but for the time being they are hosted internally. I think there is a way to ensure the solution works regardless of where the apps are hosted.
Thanks for your help!
I am not sure I understand the relationship between the title and the body of the question: I will answer the body :)
In https://azure.microsoft.com/en-us/resources/samples/active-directory-b2c-javascript-msal-singlepageapp/ you can see an example of web API token validation in Node JS. The service side logic just needs to be adjusted to point to the Azure AD tenant you are using.
The above will work regardless of where the API is hosted, given that the parameters being validated are all about logical identifiers.

Is it possible to anonymously call API App and it automatically redirect the browser to AD Login page?

During the recent Microsoft Cloud roadshow in London, something that came out of one of the talks on App Service was using AAD B2C for authentication.
It is possible currently to add Azure AD as an authentication for an API App:
Calling this API app from a browser based web app with no authorization header results in a 302 redirect immediately followed by a 401 response.
It was mentioned at the cloud event that it would be possible to call an API app anonymously from a web app, and have the azure App service handle the redirection to the AAD login page, get the token on successful login and then pass the call on to the API app and return the data.
However, I am struggling to see how this can be achieved without any responsibility on the calling web app to handle the redirect. Normally you would handle a 401 response from an API by obtaining a bearer token via AAD on the client side and sending it through as the authorisation header with the api request.
I have been through numerous examples on the Azure site and others and all of them are handling the logon/obtaining the token in the client web app.
Is this even possible?
UPDATE I just realized (as pointed out by #Darrel-Miller that you don't really want to allow the user to put the credentials in.
The only thing that is still unclear to me, is where do you want to provide the credentials for AAD?, What is it exactly what you would like to accomplish.
Even more, why would you use AAD if there no user interaction at all.
If all that you want is a secure connection you can just use the standard application key for the web api without enabling AAD. And its as pretty straight forward to just add the MS_ApplicationKey to your header and you are good to go.
As you described in your comment you have a webclient that tries to do the requests and gets the 302, that is why my original answer wast that you would use ADAL. But now that I get deeper into what you want probably what you want to use is KurveJS :
https://github.com/MicrosoftDX/kurvejs
And it has the AAD app model v2 with Active Directoy B2C.
This makes it easy to add third party identity providers such as Facebook and signup/signin/profile edit experiences using AD B2C policies
You can read more about it here:
https://github.com/MicrosoftDX/kurvejs/blob/master/docs/B2C/intro.md
Do you mean this??
https://msdn.microsoft.com/en-us/magazine/dn463788.aspx
Just use ADAL nuget package to handle the call...
You can read this from the post:
As soon as the execution hits the call to AcquireToken, you’ll get the authentication dialog shown in Figure 8. ADAL takes care of contacting the right endpoint and rendering the authentication experience provided by the server in a pop-up dialog without requiring you to write any UI code.
I hope this works for you!

User authentication through my REST API and Facebook

I'm a bit confused about how to properly and securely authenticate users using my REST API and provide and option to authenticate using other OAuth 2.0 providers as well (e.g. Facebook, Google, etc.).
Scenario
Users interact with a web application which should consume my REST API. Users should be able to login and perform CRUD operations both using username/password and by using 3rd party services such as Facebook. I will be using SSL to encrypt the traffic to the website and the API.
Without taking the 3rd party login services in consideration and by studying the various questions already asked here on SO, I thought about handling user authentication as in the picture.
Technologies and current idea
The REST API is written using JS using NodeJS and Express. The WebApp provided through another NodeJS instance is mostly AngularJS with templates which consumes the REST API.
My current idea is to let the WebApp handle the login sequence and let Facebook save their token in my DB using the callback. But this solution smells too much of workaround!
Questions
Is the authentication sequence depicted in the image correct?
How is the above authentication sequence compared to the Resource Owner Password Credential flow in OAuth2.0? Is it worth using OAuth2.0 instead of it?
How can I integrate login through 3rd parties (i.e. Facebook)? Any suggestion or (better) example?
References
passport.js RESTful auth
Login with facebook and using oauth 2.0 for authentication of REST api calls
And many others here on SO :)
My 2 cents..
The process looks good to me.. I would re-issue the token on each sign in and also keep it inside a database so tokens can be revoked easily.
Use PassportJS. Its got support for OAuth flows and supports many 3rd party integrations like FB, Twitter, Github etc..and since its a nodejs middleware.. its integration will be very tight within your application..

Resources