How to use google authentication for an angular web app and a .net web api hosted on azure - angularjs

I have an angular web app talking to a c# .net web api back end.
They are both hosted on azure app services.
Azure app services offers a suite of authentication services and I've chosen to use google auth.
I've got my google client id and secret setup in azure google auth and my web app correctly shows and prompts me for my google credentials.
My problem now, is that i need my web api back end to authenticate the web app google token. I couldn't find any articles or tutorials that demonstrates the following:
How to get and send the token to the web api? I've read that azure app service should automatically inject the necessary auth headers but any calls to my api do not include those headers. Should i manually call auth/me and add them to the request header?
How do i get my web api to authenticate the details from the request header with google auth? Do i need a separate client id for the web api or should i re-use the web app client id?
Cheers!

According to your description, I assumed that you are using the built-in Authentication / Authorization provided by Azure App Service.
AFAIK, App Service Authentication (Easy Auth) provides two flows: client-managed and server-managed flow. For the server-managed flow, the server code manages the sign-in process for you, and your backend would directly receive the token from the relevant identity provider (e.g. Google, AAD,etc.), then both generate a authenticationToken for browser-less apps and AppServiceAuthSession cookie for browser apps. Details you could follow Authentication flow.
For your angular web app, you could just use server-managed flow, after user successfully logged, you need to call https://<your-angular-app-name>.azurewebsites.net/.auth/me to retrieve the google access_token, then send the following request against your web api endpoint for retrieving the authenticationToken as follows:
POST https://<your-webapi-app-name>.azurewebsites.net/.auth/login/google
Body {"access_token":"<the-google-access-token>"}
After successfully retrieved the authenticationToken from your Web API endpoint, you could send the following subsequent requests for accessing your APIs:
GET https://<your-webapi-app-name>.azurewebsites.net/api/values
Header x-zumo-auth:"<authenticationToken-generated-by-your-webapi>"
Moreover, you could also use client-managed flow in your angular web app, you may need to directly contact with your identity provider (Google) to retrieve the access_token in your client via Auth0 or google-signin or other third-party libraries. Then you may need to both send request to your angular web app and Web API web app for retrieving the authenticationToken as the above request sample.
Do i need a separate client id for the web api or should i re-use the web app client id?
Per my understanding, you must use the same google application. For AAD authentication, you could configure a AAD app with the access permissions to another AAD app.

Related

Access Google IAP protected API from Angular

My application has 2 modules
Spring boot back-end API
Angular front-end (SPA application)
Both were deployed in Google app engine (GAE).
I used Google IAP for authentication. After enabling the IAP is there any way to generate the IAP JWT token for the different users within the organization to authenticate the APIs from the web client.
I tried token generating mechanism using the Service account. But for my scenario, I just want to authenticate and authorize users not service account. I found this reference to enable the web resource access for users, but it is using cookie based authorization. And it is not the recommended way for the application such as angular.
If you're using IAP to protect your backend api, it means your users have a Google Account or an account managed in Cloud Identity.
In your Angular front-end app, you can retrieve JWT token of your user, with Google Sign-In for Websites.
To easily integrate Google Sign-in with Angular, I recommend you to use ng-gapi from Ruben.
Main lines of the workflow :
Angular uses ng-gapi with Google Sign-in behind the scene
Users are authenticated with their Google Account
You're able to retrieve GoogleUser idToken which is a JWT token.
Each HttpRequest could be executed with Authorization: Bearer JWT
IAP will accept request.
To better understand how to use ng-gapi, check this stackblitz Demo made by creator of lib.
I also suggest you theses resources :
My answer on Stackoverflow about Angular stateless authentication workflow. Just skip the Spring Boot JWT part if you're using IAP.
Google Sign-In for Websites official docs.
Note that you need to use the OAuth 2.0 Client ID configured by Identity-Aware Proxy for your app, and add the correct Authorized JavaScript origins.
Yes, You can generate a JWT token using angular-oauth2-oidc.
Get the default IAP Web App client ID and client secret. Use AuthConfig and redirect to your link after credentials are entered; you can capture the token after they are redirected.
This link has all the details:
https://medium.com/#ishmeetsingh/google-auth-integration-with-angular-5-and-angular-oauth2-oidc-ed01b997e1df
You have told that you tried authenticating from service account. Were you able to generate JWT for service account? I am able to capture the JWT token for individual accounts and use it.
Please give more information on how you authenticated from service account.
Thanks,
Bharath

MSAL authentication and authorization from React to Web API

I have some trouble understanding the MSAL authentication and authorization. I have a single page app developed in React. I have setup the MSAL Azure SSO authentication by registering the web app on the Azure AD. Now, I have a Web API (in .Net Core) which is running on a separate app service. How do I integrate the authentication from my React app to the Web API?
Few questions coming to mind:
Do I have to register the Web API app as well similar to my React app?
Do I have to pass the auth token from my React App to the Web API?
Do I have to setup the authentication only on the Web API side (using MSAL.Net) and the React App will connect to it?
Please share your thoughts. Let me know if I can explain any better.
If you are the author of both react app and web API, you can register just one app and use ClientId for both.
Yes. If your react app is standalone app (not a part of Asp.net app) you can use msal.js to login with AzureAD and then use openId token to login to your web API. Also you can use access token to access services secured by Azure (e.g. Microsoft Graph) directly from React.
If your React app is a part of Asp.net app, you can setup Auth on server. If it's standalone app you need to use approach from 2.
If your React app is standalone app and if you are going to access "downstream" API (like Microsoft Graph) from Web API, you need to implement On-Behalf-Of mechanism on your Web API. In two words:
- user login with React app and access Web API with openId token;
- Web API acquires new access token based on token sent from client
- Web API access Microsoft Graph with this new access token.
You can find Server side example here.
Client side example from another answer works in this case, but you need to send row openId to Web API instead on access token.
P.S. You can use access token instead of idToken to access your WebAPI as well, but in this case you need to define separate scope for your WebAPI in Azure as well. After that you can use this scope to access your WebAPI and separate set of scopes to access MS Graph.
Here is a complete video tutorial and source code on how to use MSAL with React to call Microsoft Graph.
The only different in your case will be that instead of calling Microsoft Graph, you will call your own API.
Bottomline is - there is no direct integration package yet for react. Which can also be read from the official statement on the msal-js repo:
After our current libraries are up to standards, we will begin
balancing new feature requests, with new platforms such as react and
node.js.
See Here. It allows you to call Graph API from client side.

Best Practice with accessing API Server on mobile app which login using OAuth

I have the following entities:
An mobile app
in-house API Server
in-house OAuth Server
I need to implement OAuth in mobile app to the OAuth Server, and access user information in the API server afterward, and I am having trouble with how this can be achieved securely. I have only think of the following methods:
Method 1: Pass user id directly from Mobile App to API server
Login user through OAuth in mobile app (using library like AppAuth)
Store the user id retrived from OAuth in mobile app
Mobile app send the user id to the API server, so they can retrive the correct resources back to the mobile app
However, this method seems non-secure, as attacker can fake their user id when passing to the API.
Method 2: Pass OAuth access_token to API server, let API server call OAuth server again
Login user through OAuth in mobile app (using library like AppAuth)
Store the access_token retrived from OAuth
Mobile app send the access_token to the API server
API server pass the access_token to the OAuth server
OAuth server return the user info back to API server
Now API server have the user info, and can return the correct resources back to the mobile app
Method 2 seems more secure, however I don't seems to see this kind of infrastructure suggested by anybody. This method also seems resource intensive as API server need to call OAuth server every time an API is called.
So my question is:
What is the best Practice with accessing API Server on mobile app which login using OAuth?
If there is a best practice, any link to those resources?
Thank you!

How can multiple services re-use the authentication cookie?

I want to understand how a static site with no backend can use okta with other custom API services hosted on other platforms.
Scenerio:
Website is a angluar/reactjs that is hosted as a "static" website.
I'm assuming when you authenticate using okta in e.g. react/angular website I am able to store the okta session id in local storage or cookie.
How say I create a web service and host that on heroku, how can I figure out if the user has authenticated or not and re-use the session?
The scenario where you have:
A JavaScript frontend application, hosted statically
A backend web service (API), that the JavaScript app makes API requests to
is a classic single-page app (SPA) scenario. The recommended authentication flow is the OpenID Connect implicit flow.
In plain English, you are:
Setting up your JavaScript app to talk to Okta (or another OpenID Connect identity provider)
Getting an access token from the identity provider
Attaching the access token to an API request to authorize it
Your API service could be running on Heroku, or somewhere else. In your API service code, you have to validate the access token before you decide to accept the request. The API service can go back and talk to the identity provider to determine if the user's access token is still valid.
How the API service validates the token depends on what language you are using to build your API service. But, that's basic idea: the access token is what authorizes the user's requests.

Retrieve Access Token within a AAD secured Azure Web App

I have an Angular4 Application hosted in an Azure Web App and a .NET core Web API hosted in an Azure API App.
The API is secured with Azure Active Directory. Currently I use ng2-adal to aquire an access token which I inject to the headers to perform my API calls.
Now I try to remove the ng2-adal module and secure my Web App with the Authentication / Authorization feature using the same ClientId (like the API). When I browse to my website I get redirected to the AAD login and after I successfully login, I get redirected to my site. Now I wan't to call the API (that is secured with the same ClientId) within my Web App but can't find a way to retrieve the token.
Is there a way to retrieve the access token within my Angular App in this scenario?
It looks like the token is stored encrypted within the AppServiceAuthSession Cookie:
The AppServiceAuthSession is cookie which is different than a token. In this scenario, you need to modify the config of Azure app to make it acquire the access_token for the web API.
We can use the Resource Explore to modify the settings like below:
1 . locate the angular web app
2 . locate the config->authsettings(resource is the clientId of Azure app which used to protect your apps)
"additionalLoginParams": [
"response_type=code id_token",
"resource=3fa9607b-63cc-4050-82b7-91e44ff1df38"
],
3. config the redirect_uri for Azure app like below:
https://appfei.azurewebsites.net/.auth/login/aad/callback
Then after you login in the angular app, you can get the access_token via the endpoint:
https://appfei.azurewebsites.net/.auth/me
Then we need to protect the web API using the Advanced Azure Active Settings like figure below to enable the access_token could call the web API:
I've been working on this for a week.
So, I'd like to share how I got it.
I was able to have authentication for my app using AAD.
I have AppServiceAuthSession in my cookies storage.
Then on my application, I called the auth/me API.
https://yourwebsite.azurewebsites.net/.auth/me
So, it's like:
this.$http
.get('https://yourwebsite.azurewebsites.net/.auth/me').then(response => {
console.log(".auth/me", response)
}, err => {
console.log("Error: ", err)
})
I'm actually using Vue. calling your HTTP might be different.
And that's it.
I basically called the auth/me API to retrieve the information I needed.
P.S. You need to be authenticated of course.
found this solution:
just need to add your app url on
Authentication / Authorization-> ALLOWED EXTERNAL REDIRECT URLS
so the webapi will automatically accept those cookies.
ps: make sure your ajax request is passing those cookies on it.

Resources