ADAL.js with Multi-Tenant Azure Active Directory - active-directory

The sample code provided for using ADAL.js looks something like this:
window.config = {
instance: 'https://login.microsoftonline.com/',
tenant: '[Enter your tenant here, e.g. contoso.onmicrosoft.com]',
clientId: '[Enter your client_id here, e.g. g075edef-0efa-453b-997b-de1337c29185]',
postLogoutRedirectUri: window.location.origin,
cacheLocation: 'localStorage', localhost.
};
var authContext = new AuthenticationContext(config);
This works fine, but I'm trying to allow access for a multi-tenant application - users from an organisation should only be able to sign in if the application has been granted access by their account administrator.
I've implemented the first part - allowing admin users to enable - as per this example.
So at this point my application is listed in the third party's Active Directory.
I'm not sure what the correct settings should be for the tenant. I tried using 'common', but then it shows a dialog asking an individual user if they would like to grant access to the application, which is not what I'm looking for.
If I was making a straight MVC app, I'd continue on with the example above, using app.UseOpenIdConnectAuthentication on the server. But my app is a SPA, with Web Api backend, and I haven't been able to find a multi-tenant example for this scenario.

The correct way of configuring your app for authenticating with any tenant, which is what you want in your scenario, is to use common.
The per-user consent is a provisioning consideration. If you want an administrator to consent for the app on behalf of the entire organization, you can implement the admin consent flow by triggering an authentication request and appending prompt=admin_consent to it. Provided that an administrator performs an authentication flow in response to that request, Azure AD will offer to the admin the chance to consent for the app on behalf of everybody in the organization.

There is a way to configuring your app for authenticating with multiple tenant without using "common" is. You can ask user to input their email while starting the login process and pass the user type parameter like if user is using contoso.com then pass usertype = 0 else 1;
After declaring the two tenants and its client id, you can initialize the authContext by making it a function.
import AuthenticationContext from "adal-angular/dist/adal.min";
const adalConfig1 = {
instance: 'https://login.microsoftonline.com/',
tenant: '[Enter your first tenant here, e.g. contoso.onmicrosoft.com]',
clientId: '[Enter your first client_id here, e.g. g075edef-0efa-453b-997b-de1337c29185]',
postLogoutRedirectUri: window.location.origin,
cacheLocation: 'localStorage', localhost.
};
const adalConfig2 = {
instance: 'https://login.microsoftonline.com/',
tenant: '[Enter your second tenant here, e.g. contoso1.onmicrosoft.com]',
clientId: '[Enter your second client_id here, e.g. g075edef-0efa-453b-997b-de1337c29185]',
postLogoutRedirectUri: window.location.origin,
cacheLocation: 'localStorage', localhost.
};
export const authContext = (usertype)=>{
if(usertype=== 0){
return new AuthenticationContext(adalConfig1)
}else{
return new AuthenticationContext(adalConfig2)
}
};
Use this authContext(usertype) to user login in function.

Related

Client - API authentication flow with Microsoft Azure AD

I'm building a react frontend application with a spring backend that is secured with azure ad.
I can't get the authentication flow to work.
In azure ad, I have registered 2 applictions:
API: Default configurations and under "Expose an API" I have added a scope with api://xxxx-api/Access.Api and also added the client application. Under "App Roles" I have added the roles "User" and "Admin". I have assignes both roles to myself.
Client: Registered as SPA with redirect to http://localhost:3000 where the react app is running. Did not check the two boxes for the token to enable PKCE. Under "API permissions" I added the "Access.Api" scope from the api app and granted admin consent.
In the react app I'm using #azure/msal-browser and #azure/msal-react.
My authConfig looks like this:
Then I'm just using useMsalAuthentication(InteractionType.Popup); to sign the user in.
All this works as expected and I'm getting a token back. If I parse this token in jwt.io,
I get "iss": "https://sts.windows.net/42xxxxx-xxxxx-xxxxxx-xxxxx/",
"scp": "openid profile User.Read email", "ver": "1.0",.
However, I do not see the scopes or roles for my API app.
I'm then using an Axios request interceptor to provide the bearer token on every API request:
const { instance, accounts } = useMsal();
const account = useAccount(accounts[0]);
axios.interceptors.request.use(async (config) => {
if (!account) {
throw Error('No active account! Verify a user has been signed in.');
}
const response = await instance.acquireTokenSilent({
...loginRequest,
account,
});
config.headers.Authorization = `Bearer ${response.accessToken}`;
return config;
});
The token is successfully added to the header of each request.
My spring application however fails to validate this token.
My spring config:
I could implement the token validation myself if that is an issue here, but how do I fix, that the bearer token does not contain the roles that I need to check if the user has access to specific resources on the api?
I figured it out.
Basically the scopes openid, email and profile should only be used when requesting an ID token. The ID token contains all roles exposed in the client app.
If these scopes are used when requesting an access token, the token will contain no roles or scopes at all. Only use the scope from the api app that is exposed in the client app when requesting an access token, and the roles will show up in the access token.

InteractionRequiredAuthError: invalid_grant: AADSTS50076

Error message: Due to a configuration change made by your administrator, or because you moved to a new location, you must use multi-factor authentication to access 'bxxx-xxxx-xxxxa'.
I am getting this error intermittently, while accessing token with auth code.
Token endpoint fails with error code 400.
Request body in browser contains:
POST: https://login.microsoftonline.com/tenantID/oauth2/v2.0/token
clientId,
scope - xxxxxxxx/.default openid profile offline_access
grant_type: authorization_code
code
redirect_uri
and here is MSAL configuration: (we are using react-msal 1.4.3)
const msalConfig = {
auth: {
clientId: env?.ClientId,
authority: env?.Authority,
redirectUri: env?.RedirectUri,
postLogoutRedirectUri: env?.PostLogoutRedirectUri,
},
cache: {
cacheLocation: "localStorage",
storeAuthStateInCookie: true,
},
scopes: [env?.AuthScope],
}
Please let me know if anyone has encounter this issue before and found any solution for it.
• It is because your administrator has enabled the security defaults setting in ‘Manage security defaults’ section in Azure AD tenant properties as shown below in the snapshot. When you enable this option, Azure AD mandates all users to register for Azure AD multi-factor authentication, requires the same for administrators and enforces it, blocks legacy authentication protocols, and protects privileged activities like access to the Azure portal.
Thus, if you are assigned a role of ‘Administrator’ of any sort, i.e., Global, Authentication, Application, Billing, Exchange, etc., then your ID would be required to do multi-factor authentication. Also, please ensure that you are not using any older protocol and legacy authentication since those doesn’t have access to multi-factor authentication.
As a result, this would help in resolving the issue and the subsequent error that you are facing. For more information, kindly refer to the below links given: -
https://learn.microsoft.com/en-us/azure/active-directory/fundamentals/concept-fundamentals-security-defaults
https://learn.microsoft.com/en-us/answers/questions/494959/aadsts50076-ue-to-a-configuration-change-made-by-y.html

Is it possible to implement switch account feature using msal.js for SPA website?

I am trying to implement switch account feature for my SPA website. I am able to login an account that matches the current user that launched the browser. But if i prompt for account selection and provide a different account email id to login then it still using the current user that launched the browser to login and retrieves the id token. I have a service account that i would like to use but am not able to get token for the service user account from my actual windows account browser instance. Both of these accounts are in same tenant (company tenant) and i can log them in if i launch the browser (Run as User feature) with the corresponding windows Account. Is it possible to implement switch account using msal.js 1.2.2 version? if yes, can i get a sample on how to implement the feature?
The below is my msal config
var msalConfig = {
auth: {
clientId: config.appServiceConfig.clientId,
authority: config.appServiceConfig.authority,
redirectURI: config.appServiceConfig.redirectURI,
navigateToLoginRequestUrl: false
},
cache: {
cacheLocation: "sessionStorage",
storeAuthStateInCookie: true
}
};
var requestObj = {
scopes: ["User.ReadBasic.All"],
prompt: "select_account",
loginHint: "serviceaccount#xxx.com",
authority: config.appServiceConfig.authority
};
Appreciate any help!!!
Thanks
Sarat.

The Reply URL specified in the request does not match the reply URL's configured for the application

I am currently using Microsoft adal angular for Azure active directory authentication and below if the configuration settings for the same.
MsAdalAngular6Module.forRoot({
tenant: 'xxxxxxxxxxxxxxxxxxx',
clientId: 'xxxxxxxxxxxxxxxxx',
redirectUri: window.location.origin,
endpoints: {
"xxxxxxxx": "xxxxxxxxxxxxxx",
},
navigateToLoginRequestUrl: true,
cacheLocation: 'localStorage',
loadFrameTimeout: 60000
}),
I have set reply URL as https://xxx.azurewebsites.net/ in Azure app registrations.
The above configuration works fine if I use https://xxx.azurewebsites.net/ and enter into the application. But when I use https://xxx.azurewebsites.net/dashboard and enter my credentials it is throwing the error mentioned in the subject and not allowing me to go in.
I know that the Azure has blocked wild card configurations in Active directory. Is there a way for me to configure the settings to successfully authenticate If I copy-paste any deep link from the application.
Any help would be really appreciated and thanks in advance.
When the redirect_uri in the authorization request mismatches the redirect url configured in Azure AD registrations, you will encounter this error.
So if you want to use https://xxx.azurewebsites.net/dashboard in your request, you should also add it as the redirect url of your Azure AD registrations.
Update:
Based on our discussion, you just need to specify the redirect URL in your code as the same url as what you have configured in your Azure AD app: https://xxx.azurewebsites.net to meet your requirement.

Integrate Azure AD with AngularJS and call CORS web api

After going through the article https://learn.microsoft.com/en-us/azure/active-directory/develop/quickstart-v1-angularjs-spa, we have created a web application named ToDoSpa and web api named ToGoApi registered in Azure Active Directory and are able to authenticate but the problem lies in consuming the web api including the endpoints as
AADSTS65001: The user or administrator has not consented to use the application with ID '2528e8f3' named 'ToDoSpa '. Send an interactive authorization request for this user and resource.
Trace ID: df70a02e-6a53-4899-8319-0ba440540500
Correlation ID: 699515a6-dccb-421e-92ae-e9b5a700ad1b
Timestamp: |interaction_required".
Client Id:
ToDoSpa->2528e8f3
ToGoApi->815933a4
In ToDoSpa,we have defined the scopes for the application ToDoSpa as "User.Read and Directory.Read.All" and authorized the client application using the client ID of web api(815933a4) in Expose API. In App permission, we have included ToDoSpa and have grant consent the application.
app.js
var endpoints = {
"https://graph.microsoft.com": "https://graph.microsoft.com",
"https://localhost:44392/api/weather": "https://firstupconsultants.onmicrosoft.com/ToGoApi"<!--localhost:App Id Uri of Server-->
};
adalProvider.init({
instance: 'https://login.microsoftonline.com/',
tenant: '<tenant-id>',
clientId: '<client-id of server>',
endpoints: endpoints,
extraQueryParameter: 'prompt=admin_consent'
}, $httpProvider);
}]);
//Get
weather1.getWeather = function () {
return $http.get("https://localhost:44392/api/weather").then(succeessCallback, failedCallback);
function succeessCallback(weather) {
//$scope.weather = weather.data;
weather1.items = weather.data;
}
function failedCallback(error) {
console.log("An error has occurred:", error);
}
}
web.config
<add key="ida:Tenant" value="<tenant-id>"/>
<add key="ida:Audience" value="https://firstupconsultants.onmicrosoft.com/ToGoApi"/>
<!--localhost:App Id Uri of Server-->
Typically, when you build an application that uses application permissions, the app requires a page or view on which the admin approves the app's permissions. This page can be part of the app's sign-in flow, part of the app's settings, or it can be a dedicated "connect" flow.
When you're ready to request permissions from the organization's admin, you can redirect the user to the Microsoft identity platform admin consent endpoint.
Here is sample URL for the same:
GET https://login.microsoftonline.com/{tenant}/adminconsent?
client_id=6731de76-14a6-49ae-97bc-6eba6914391e
&state=12345
&redirect_uri=http://localhost/myapp/permissions
When you want to enable the users on other tenant can use the application, the application required to give the consent first. To do that you can make a HTTP request to grant the admin consent easily by using the prompt parameter.
You can read about this in detail in below doc:
https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow#request-the-permissions-from-a-directory-admin
Additional reference:
https://blog.mastykarz.nl/implementing-admin-consent-multitenant-office-365-applications-implicit-oauth-flow/
Hope it helps.

Resources