How can multiple services re-use the authentication cookie? - reactjs

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.

Related

Azure AD integrate with frontend React and backend GoLang

I have a separate structure for backend using GoLang Gin and frontend ReactJS and would like to integrate the Azure AD Oauth2 login.
However, it's ok to authenticate GoLang App or React App, but how to pass the auth info to the backend when I authenticate in frontend using msal-react?
In my current backend API, I use JWT like this to protect APIs:
v1.Use(jwtauth.JWTAuth())
or should I authenticate the backend and pass the info to frontend? but I cannot get it to redirect(Azure login) since they are in different port...
Thanks!
The typical pattern is:
Front-end (React app in your case) uses msal (or other compatible library) to redirect the user to login
Front-end acquires access token for back-end using a scope defined in API app registration (or same app registration)
Front-end attaches access token to back-end requests
Back-end validates access token (signature using public keys from Azure AD, expiry time, audience, issuer, scopes etc.)
In .NET we configure an "authority" for JWT authentication, e.g. "https://login.microsoftonline.com/", and the authentication handler then downloads metadata + public keys from "https://login.microsoftonline.com//.well-known/openid-configuration".
It might be possible to configure something like this for your library as well.
Scopes you typically have to check yourself.

React SSO using SAML without web server

I have a web app developed using Create-react-app
I host it on IIS, the IIS only response to load the app, there is no server side logic on it (no Express or any other web server)
The app is using a RESTful API on the same IIS, it is out of my control (I cannot make change).
Now one of my client request to add SAML SSO to our app.
I would like to know:
in normal situation, which one is the Service Provider? My IIS Web server? or the API service?
For my case, I cannot implement SAML to API service, my web service only used to load my app without server side logic, how can I implement SAML?
Could any one give me some React implement SAML SSO tutorial or article for reference?
Thanks for any help, any information or suggestion are welcome!
in normal situation, which one is the Service Provider? My IIS Web server? or the API service?
I assume the client wants to authenticate the users using their internal IdP. So your application is the SP. But you will have to define different token service (details below).
With SPA (a single-page-applications) I see the problem, in SAML the user is redirected or posted away from the SAML request and SAML response.
I have a login page to enter id/pw, post them to API server Login endpoint to authenticate and get back a JWT token. After that we use that token in API calls for authentication
The API services are using a JWT token issued based on the provided username/password. I'd recommend to extend the token service (or use a different service) to issue a JWT token based on the provided SAML response - a token swap service. In many OAuth implementations it's called SAML grant type.
I cannot implement SAML to API service, my web service only used to load my app without server side logic, how can I implement SAML?
Usually after the authentication the user is redirected or posted to the SAML ACS endpoint URL, where the server can create sort of session (cookie, parameters, token, ..) and the user is redirected to a URL returned the web page with the session information.
If you are using an SPA, you could use a popup window or SAML with redirect (not with post), where the page could read the SAML response parameters (assertion, signature, ..) and use them in the token swap service mentioned above.
When processing the SAML response, try to use some mature, known, out-of-box libraries, it's a security service and not doing it properly may cause security weaknesses. But you need to do that on the server side, as at the end you need the JWT token consumed by the APIs.

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

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.

How to configure a WebApp & WebApi with different AAD App IDs?

I currently have two app services
Web App (Asp.net core 2 w/ front end in react)
Web Api (Asp.net core 2)
Note: Both are configured with different Azure active directory app id.
user signs into Web App and retrieves a token for it's own appId/ClientId/ClientSecret stored in tokencache.
from the WebApp, the user wants to talk to a WebAPI but needs to get a token since it's protected with AAD as well but it's a different app id/client id/client secret.
Problem:
When I try to do a AcquireTokenSilentAsync() for the web api, I get an error throwing that I the token is not in the cache?
It also seems that with depending if your using AAD v2.0 or v1.0 will determine if the web app and web api can have different app ids. So it seems like i would have to use AAD v1.0. With Asp.net core 2, it's not clear to me what OpenIdConnect is using or configured to use under the covers.
Question:
It's not clear to me why the acquire token silent async didn't work and failed. Does that only look for the token in the cache; otherwise it fails?
Is it possible to configure the token from web app to have permission to access web api resources. I notice that in the azure portal, you can selected resources like microsoft graph, but I don't know how you would associate a custom API. In my case, I want to get it running on my local machine before I move it all to azure.
If the web app token does not have permission to access the web api, do i need to do another login authentication with the user even thou both are within the same tenant?
Any Advice appreciated,
Derek
Yes, AcquireTokenSilentAsync will look into the cache, and see if it can find tokens. If it does, it will check to see if the access token is still valid and return that back. If the token is expired, it will use the refresh token to fetch a new access token and return that back. When this call fails, it's an indicator you need to perform an AcquireTokenAsync (which will likely show UI in the case silent already failed).
Yes, you can associate a web app to get tokens for your own custom web API. I'd recommend using Azure AD v1.0 (register the app in the Azure portal, ADAL library). You'll need to register the two apps (web app and the api), both will be type web app/api. In the API, you can register an App ID URI which will act as the resource identifier for this API. In your web app, you'll want to go into the Required Permissions, and add the Web API you have registered as a permission. Then in your web app, you'll need to use the ADAL library (alongside an OpenID OWIN middleware) to acquire a token for the resource as specified by the App ID URI field. Here's a code sample that implements the exact scenario you're describing (Web App/API in ASP.NET Core).

ASP.NET Web API to issue cookie for SPA on different domain

My AngularJS SPA and its ASP.NET WebAPI 2 API are located on different domains. SPA user is authorized in API by obtaining JWT token from API auth server and then SPA sends each request with Authorization Bearer request header containing this token to access protected API endpoints.
Now we need to expose some API endpoints to be directly accessible by users when they are logged in to SPA. But I'm not sure how to implement it because we don't use cookies and our API is located on different domain than our SPA.
Is it possible to configure ASP.NET WebAPI 2 to issue cookie to a different domain (API domain) when POST request with credentials is sent from SPA from another domain?
Consider that cookie is being stored in client-side not in your server-side. You can add some tracker (i.e Google Analytics, or create your own tracker) to store the log data from users based on their tokens or their server variables like ip address, session key and so on. Notice that tracker service will be launched on server-side and the tracker on the client-side like trackers javascript snippet-codes.
Hope this can be helpfull. Regards.

Resources