Authenticating against a webapi using azure b2c from an spa (angular and adal.js) - angularjs

I'm trying to authenticate my SPA (angular.js and adal.js (similar to the
https://github.com/Azure-Samples/active-directory-angularjs-singlepageapp-dotnet-webapi example)
My AD is a azure b2c preview tenant.
I can successfully log in to my webapi from my Website, but not from the JS SPA via angular.
My Setup:
Webapi and Website share the same clientid (does only seem to work this way)
The SPA has its own clientid, because otherwise i get "api version not supported" errors when trying to log in.
I have enabled oauth2AllowImplicitFlow for all applications, granted application permissions from the spa to the webapi.
Cors is enabled on the Webapi and the SPA.
I even seem to be able to get a token after completing the login, but when i try to call my api, i get an access denied for this request.
Is this supposed to work this way? I could not find an example of how to use b2c together with a spa and the api running on different servers.
Thanks in advance
Peter

Officially it's not supported by Microsoft, but with some modifications of experimental branch on github azure-activedirectory-library-for-js you can get it working.
Fix logout url to v2.0 endpoint of oauth2 protocol with the policy parameter in the logOut method of adal.js at line 546:
var urlNavigate = this.instance + tenant + '/oauth2/v2.0/logout?' + logout + (this.config.extraQueryParameter ? '&' + this.config.extraQueryParameter : '');
The username property is never set in method _createUser of adal.js. The username is used in renew token process, fix it by adding this three lines:
if (parsedJson.hasOwnProperty('emails')) {
user.userName = parsedJson.emails[0];
}
Finally, in adal-angular.js at line 146, acquireTokenSilent is called with wrong type parameter. This method accept only array type as scopes parameter, fix it by placing clientId in array:
_adal.acquireTokenSilent([_adal.config.clientId], null, function (error, tokenOut) {
I already pulled a request on github about this, you can use it as reference.
When you initialize adal provider on angular put your b2c sign in policy in extraQueryParameter like this:
adalProvider.init({
tenant: 'tenant.onmicrosoft.com',
clientId: 'clientid',
extraQueryParameter: "p=B2C_1_SignIn"
}, $httpProvider);

Looks like an AzureAD B2C scenario sample code for SPA was just released on github. See it here.
"The sample shows how to build a web application using Hello.js that performs identity management with Azure AD B2C. The app is a simple web application that performs sign-in, sign-up, and sign-out functions with sign-in and signIn-signUp policies and also edit profile using EditProfile Policy."
NOTE: At the time of this answer the functionality is still in "preview"

This is not currently supported.
Single Page Applications (Javascript)
Many modern applications have a Single Page Application (SPA)
front-end written primarily in Javascript and often using a SPA
frameworks such as AngularJS, Ember.js, Durandal, etc. This flow is
not yet available in Azure AD B2C preview.

Related

If possible, how to register front-end and back-end in a single application in Azure AD?

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

Migrate from msal angular to azure webapp authentication

I'm working on a web application deployed on an azure webapp authenticated with Azure AD.
It is mostly based on the angular template for ASP.Net Core. The backend hosts the frontend in a ClientApp directory.
For the authentication, the frontend works with the msal-angular plugin which on access redirects to the Azure AD authentication page. After login, the login page redirects back to the frontend, which catch the token, and makes all the calls to the backend with the token in the authorization bearer header.
The .Net Core backend is configured with :
services.AddAuthentication(AzureADDefaults.BearerAuthenticationScheme)
.AddAzureADBearer(options => Configuration.Bind("AzureActiveDirectory", options));
Finally, to make all these works, I have in the Azure AD app registration one entry for the backend and another for the frontend.
This works well, but we want to move away from that to use the Authentication directly on the webapp.
This way we could secure even more the application which would not even be downloaded if the user is not authenticated.
How do I manage to do that ?
Do I need to remove all authentication code from the backend and frontend ?
Do I still need 2 entries in the app registration on azure AD or one is now enough ?
How will I know which user is connected ? Actually I use the IHttpContextAccessor to get the UPN Claim.
Thanks for the help

How to integrate my activiti app (version 6) with Azure active directory endpoint v2.0 without using ADAL.js or MSAL.js

I have an Activiti app which needs to be integrated with the Azure Active directory for user sign in and authentication. The application is registered on the Azure AD and I have the following information:
tenant ID
CID
key
I am trying to follow the steps in the official documentation here, using the implicit flow.
All the examples I could find for it make use of the msal.js library to authenticate users with Microsoft Azure Active Directory accounts. But i need to achieve this without using any libraries. How do I proceed with this?
How and where in the activiti-UI do i need to put in the code to hit the following URL given in the steps
https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize?client_id=6731de76-14a6-49ae-97bc-6eba6914391e&response_type=id_token&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F&scope=openid&response_mode=fragment&state=12345&nonce=678910
Any examples on this would be of great help!!
Thanks in advance!
For the doc you choose, it does not use a library.
To refer to this doc, your app is required to be registered in the v2 endpoint, like Application Registration Portal or app registration(preview) in Azure Portal. And you also need to enable Allow Implicit Flow for the Web client.
Send the sign-in request in your browser:
https://login.microsoftonline.com/{tenant-name}/oauth2/v2.0/authorize?
client_id=your application id
&response_type=id_token
&redirect_uri=your application redirect urls
&scope=openid
&response_mode=fragment
&state=12345
&nonce=678910
The response like this:
By this, you could get the id_token for the sign-in user. If you want to get the access_token, you need to replace openid in the scope with the resource url with the format(like microsoft graph: https://graph.microsoft.com/User.Read), and replace the id_token with access_token in the response_type.
The access_token response like this:
If you want to parse the token, you could use jwt.io.

Azure AD B2C Angular front + Django Backend

We need to create application based on Angular, Django and with integrations with Azure B2C AD.
Now, we have done part with Angular, we make request to Azure B2C, when user will be sign in, it return to angular app with ?id_token.
And there is our problem, because frontend need to communicate with our backend written in Django. We need to secure this connections and get know who is making request.
We want to create something like that:
angular->Azure B2C
Azure B2C->(with id_token)->angular
angular->Django(with id_token)->create session->angular(send session_key)
angular->Django(with session_key->angular(with requested data)
And there is problem, we don't know how to verify that user is successfully signed in in Azure. (Part which I make italic).
You should get an Authorization Code from AAD B2C and not a token, as the OAuth 2.0 authorization flow describes it.
So you should do:
Angular -> Azure B2C
Azure B2C -> (with auth code) -> Angular
Angular -> Django(with auth code) -> retrieve access_token and refresh_token
Angular -> Django Secured API (with access_token)
We just released our own implementation of Angular + AAD B2C (running on ASP.NET Core but the logic should be the same, you will only need to find the Django equivalent), if you want to see how to do it: https://github.com/3DSemantix/angular-asp.net-core-aad-b2c

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