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.
Related
I have an application stack with a React SPA frontend and an Asp.net core web-api backend. Both resources had been successfully registered in AzureAD each with its own app and the authentication and authorization processes are working fine. However, would it be possible to use the same registration for both the front and backend in AD?
When using the AD Application ID from the backend in React:
auth: {
clientId: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
authority: "https://login.microsoftonline.com/<tenantId>",
redirectUri: "http://localhost:3000"
}
I get the following error:
ServerError: invalid_request: AADSTS90009: Application 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'(api://xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx) is requesting a token for itself. This scenario is supported only if resource is specified using the GUID based App Identifier.
I am using the MSAL library for the frontend.
Both the applications (front end and back end) need to be registered for sure in Azure AD.
As you are using client id of backend which is api to be secured , the Error is occurring.
Update client-id, tenant-id, redirect URI of front end application not backend api in configuration file based on application registration in Azure AD.
Then make sure to expose an API and grant admin consent to the API with required permissions.
Yes, this is possible. Your provider configuration looks correct, so check to make you app registration is setup properly. You will need the following things:
An SPA platform configuration with a redirect URI of http://localhost:3000
Add a scope (under 'Expose an API') and make sure your Application ID URI is created
Use the new scope in your MSAL authentication template
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.
I have an app service say https://blahablah.azurewebsites.net to which I have hosted an ASP. Net web api project(An api that returns list of to do items by GET request), so that I can access the API without any authentication using https://blahablah.azurewebsites.net/api/TodoItems as i had TodoItems as my controller.
Now when I create an Azure AD and set Advanced Authentication of the app service; I can't access the api on the previous endpoint; When I use postman with the client id, secret, auth and token endpoints, it says my redirect URL is not valid;
So what should be my redirect URL? How can i successfully send a GET request from POSTMAN?
Update 1: My endpoints were wrong, and I corrected it to login.microsoftonline.com instead of login.microsoft.com, so I'm getting the access token, but when I'm sending a get request to above api with that token in header, it still says 401 unauthorised.
And i'm using redirect url as https://www.getpostman.com/oauth2/callback
Update 2: Here is my configuration
1)I have 2 AAD apps: blahablahAAD aap and PostmanAAD app
2)For app service, blahablah i use the first AAD app thru Express authentication of Azure Active Directory;
3)I have made https://blahablah.azurewebsites.net/api as the first AAD app's Application ID URI, and hence am able to expose https://blahablah.azurewebsites.net/api/TodoItems with TodoItems as scope.
4)I have added the API to "API permissions" of the first AAD app; (uptil now it works well in browser asking me for login and then taking me to the endpoint;)
5) For the PostmanAAD, I use it's client id,secret in Postman and get the token; I send it as request header to API;but it failss
6) I have added PostmanAAD's client id in "Expose API->add client application" of blahablahAAD.
7) I have done step 4 for PostmanAAD also
8) I have granted admin consent to all in default directory.
Note: I haven't added any authorization related code to my ASP .NET web api project that i hosted as app service, but i believe i can access it without writing code(as in AAD will do the task for me).
Set resource url as the guid of the azure ad app instead of application id url.
Click azure ad app and choose Application Id in Overview.
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.
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.