Cannot authenticate: Azure authentication in React app - reactjs

I'm trying to set up Azure authentication from a React app following this tutorial:
https://learn.microsoft.com/en-us/azure/active-directory/develop/tutorial-v2-react
After setting up Azure and running it, I get this error:
ClientConfigurationError: url_parse_error: URL could not be parsed into appropriate segments. Given Error: Given url string: common/
Below is the configuration file 'authConfig.js'.
I don't know what I'm doing wrong as I'm doing this for the first time and I don't understand the error messages, nor do I find anything relevant in the docs other than what I've tried, changing the authority string.
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
import { LogLevel } from "#azure/msal-browser";
/**
* Configuration object to be passed to MSAL instance on creation.
* For a full list of MSAL.js configuration parameters, visit:
* https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/configuration.md
*/
export const msalConfig = {
auth: {
clientId: "912fcdde-6306-4397-96ec-d7e24418d206",
// authority: "bde20525-a858-4726-a4c7-48bd8239499f",
// authority: "emtechdemo07052021.onmicrosoft.com",
authority: "common",
redirectUri: "http://localhost:3000"
},
cache: {
cacheLocation: "sessionStorage", // This configures where your cache will be stored
storeAuthStateInCookie: true, // Set this to "true" if you are having issues on IE11 or Edge
},
system: {
loggerOptions: {
loggerCallback: (level, message, containsPii) => {
if (containsPii) {
return;
}
switch (level) {
case LogLevel.Error:
console.error(message);
return;
case LogLevel.Info:
console.info(message);
return;
case LogLevel.Verbose:
console.debug(message);
return;
case LogLevel.Warning:
console.warn(message);
return;
}
}
}
}
};
/**
* Scopes you add here will be prompted for user consent during sign-in.
* By default, MSAL.js will add OIDC scopes (openid, profile, email) to any login request.
* For more information about OIDC scopes, visit:
* https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-permissions-and-consent#openid-connect-scopes
*/
export const loginRequest = {
scopes: ["User.Read"]
};
/**
* Add here the scopes to request when obtaining an access token for MS Graph API. For more information, see:
* https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/resources-and-scopes.md
*/
export const graphConfig = {
graphMeEndpoint: "https://graph.microsoft.com"
};

Please try by changing the value of authority to:
https://login.microsoftonline.com/common
If you want to authenticate users against a specific tenant, please specify that tenant id or fully qualified tenant name instead of common. Something like:
https://login.microsoftonline.com/bde20525-a858-4726-a4c7-48bd8239499f
- OR -
https://login.microsoftonline.com/emtechdemo07052021.onmicrosoft.com
For more details, please see here (2nd bullet point which talks about the values for msalConfig section).

Related

Client secret not provided in request error - Keycloak, React, Typescript

So I'm fairly new with using Keycloak and I'm using this tutorial to install it with my React & TS app.
https://blog.devgenius.io/security-in-react-and-webapi-in-asp-net-core-c-with-authentification-and-authorization-by-keycloak-89ba14be7e5a
That author says we should set the Access Type to confidential.
I've done the settings he says there (literally the same) and I get
{"error":"unauthorized_client","error_description":"Client secret not provided in request"}
my keycloak.json (which is in the public/ folder)
{
"realm": "best-realm",
"auth-server-url": "http://localhost:28080/auth/",
"ssl-required": "external",
"resource": "best-react",
"verify-token-audience": true,
"credentials": {
"secret": "secret"
},
"use-resource-role-mappings": true,
"confidential-port": 0
}
KeycloakService.tsx
import Keycloak from "keycloak-js";
const keycloakInstance = new Keycloak();
/**
* Initializes Keycloak instance and calls the provided callback function if successfully authenticated.
*
* #param onAuthenticatedCallback
*/
const Login = (onAuthenticatedCallback: Function) => {
keycloakInstance
.init({ onLoad: "login-required" })
.then(function (authenticated) {
authenticated ? onAuthenticatedCallback() : alert("non authenticated");
})
.catch((e) => {
console.dir(e);
console.log(`keycloak init exception: ${e}`);
});
};
const KeyCloakService = {
CallLogin: Login,
};
export default KeyCloakService;
Why am I getting this error? I've read some posts that access type confidential doesn't work anymore with a JS adapter. But those posts were older than the posting date of that tutorial (it is written in may 2022). So I don't know what to believe.
Can anybody help me understand this error and teach me how to fix it?
Thanks.
In keycloak.js removed "credential" access type option.
Official comment about this since Keycloak 8.0.0
https://www.keycloak.org/docs/latest/release_notes/#credentials-support-removed-from-the-javascript-adapter
You should be use public option in front-end side.
The public option with PCKE(Proof Key for Code Exchange) is protect to steal token that is intended for another app.
Understanding benefits of PKCE vs. Authorization Code Grant
This web site shows how to use PCKE from Keycloak
https://www.appsdeveloperblog.com/pkce-verification-in-authorization-code-grant/

Setting up Azure B2C with React

I am trying to configure my react/.NET 5.0 application to work with Azure B2C. I have everything set up , I have tried to run this against an MVC application and I get the login screen. But for some reason, when I try to redirect from a react page, I keep getting the same error. There appears to be almost no real good documentation for this as well. This is my authConfig file.
export const msalConfig = {
auth: {
clientId: process.env.REACT_APP_ADB2C_CLIENT_ID
, authority: process.env.REACT_APP_ADB2C_AUTHORITY
, knownAuthorities: [process.env.REACT_APP_KNOWN_AUTH]
, clientSecret: process.env.REACT_APP_CLIENT_SECRET
, reponseType: 'code'
},
cache: {
cacheLocation: 'sessionStorage'
,storeAuthStateInCoolie: false
}
};
const b2cPolicies = {
name: {
signUpSignIn: "B2C_1_cp_signin_up"
, forgotPassword: "B2C_1_cp_forgot_pwd"
, editProfile: "B2C_1_cp_edit_profile"
},
authorities: {
signUpSignIn: {
authority: `https://${process.env.REACT_APP_TENANT_LOGIN}/${process.env.REACT_APP_TENANT}/${process.env.REACT_APP_SIGNUP_POLICY}`,
},
forgotPassword: {
authority: `https://${process.env.REACT_APP_TENANT_LOGIN}/${process.env.REACT_APP_TENANT}/${process.env.REACT_APP_FORGOT_POLICY}`,
},
editProfile: {
authority: `https://${process.env.REACT_APP_TENANT_LOGIN}/${process.env.REACT_APP_TENANT}/${process.env.REACT_APP_EDIT_POLICY}`
}
},
authorityDomain: process.env.REACT_APP_TENANT_LOGIN
}
export const loginRequest = {
scopes: ["openid", "profile"],
};
I keep running into this error when I click on the link to redirect.
Any help with this would be great.
The reply URL must begin with the scheme https. Please check if reply urls are configured correctly which must be same in azure portal and in code .
Check if the callback path is set to identity provider something like /signin-oidc for redirect url .(And make sure you have unique callback if multiple urls are used.
such as https://contoso.com/signin-oidc.
The CallbackPath is the path where server will redirect during authentication. It's automatically handled by the OIDC middleware itself, that means we can't control the logic by creating a new controller/action and set CallbackPath to it
If you have check marked id_token in portal, try redirecting to home page ,instead of api actions directly.
Change the cookies to be set as secure using this in start up class
services.Configure(options =>
{
options.CheckConsentNeeded = context => true;//add if consent needed
options.MinimumSameSitePolicy = SameSiteMode.None; // else try SameSiteMode.Lax;
options.Secure = CookieSecurePolicy.Always;
});
use Microsoft.AspNetCore.HttpOverrides; reference in startup.cs class, by including the nuget package.
Also check and Add > app.UseHttpsRedirection(); above app.authentication(); in startup configure method.
then try again.
If not try to set ProtocolMessage.RedirectUri to the HTTPS url
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(options =>
{
Configuration.Bind("AzureAdB2C", options);
options.Events = new OpenIdConnectEvents
{
OnRedirectToIdentityProvider = async ctx =>
{
/* Redirect Uri modified for https protocol */
ctx.ProtocolMessage.RedirectUri = urlWithHttps
}
}
});
Or you can pass login hint :Please refer this doc.
References:
Tutorial: Register an application - Azure AD B2C | Microsoft Docs
Configure authentication in a sample web application by using Azure Active Directory B2C | Microsoft Docs

What is the structure of the config file for Azure B2C Authetication using react app along with the Authority link structure?

I am trying to get the perfect structure of config and the authority url for my B2C auth application that will be integrated with Azure and React. I did get this structure for my config file and the auth link is specified as in the comments. but I am not able to get the popup screen and the error says that the authority link is invalid.
import { LogLevel } from "#azure/msal-browser";
/**
* To learn more about user flows, visit: https://learn.microsoft.com/en-us/azure/active-directory-b2c/user-flow-overview
* To learn more about custom policies, visit: https://learn.microsoft.com/en-us/azure/active-directory-b2c/custom-policy-overview
*/
const tenantName = "TenantName";
const signInPolicy = "Plicy_For_SignIn";
const applicationID = "CliendId";
const reactRedirectUri = "http://localhost:3000"; //RedirectURL
// Formatted as https://{b2ctenantname}.b2clogin.com/tfp/{b2ctenantguid or full tenant name including onmicrosoft.com}/{signuporinpolicyname}
const AuthorityUrl = `https://${tenantName}/tfp/${tenantName}/${signInPolicy}`;
/**
* https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/configuration.md
*/
export const msalConfig = {
auth: {
clientId: applicationID,
authority: AuthorityUrl,
redirectUri: reactRedirectUri,
},
cache: {
cacheLocation: "sessionStorage",
storeAuthStateInCookie: false,
},
system: {
loggerOptions: {
loggerCallback: (level, message, containsPii) => {
if (containsPii) {
return;
}
switch (level) {
case LogLevel.Error:
console.error(message);
return;
case LogLevel.Info:
console.info(message);
return;
case LogLevel.Verbose:
console.debug(message);
return;
case LogLevel.Warning:
console.warn(message);
return;
default:
return;
}
},
},
},
};
/**
* https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-permissions-and-consent#openid-connect-scopes
*/
export const loginRequest = {
scopes: ["User.Read"],
};
After using the same and passing it to the root of the Index.js file by wrapping it with MsalProvider and calling the instance for a popup login is not working.
I am using the packages that are mentioned in the official documents #azure/msal-react and #azure/msal-browser
The Error that I am getting is a 400 followed by a message that says:
ClientAuthError: endpoints_resolution_error: Error: could not resolve endpoints. Please check network and try again. Detail: ClientConfigurationError: untrusted_authority: The provided authority is not a trusted authority. Please include this authority in the knownAuthorities config parameter.
I need some help on this!!
Thabk you!!
Here is an example authority URL, as per the guide here:
authority: "https://contoso.b2clogin.com/contoso.onmicrosoft.com/Your-B2C-SignInOrSignUp-Policy-Id"
Your code has:
const tenantName = "TenantName";
const signInPolicy = "Plicy_For_SignIn";
const AuthorityUrl = https://${tenantName}/tfp/${tenantName}/${signInPolicy}
Which results into:
https://TenantName/tfp/TenantName/Plicy_For_SignIn -> that does not conform to the sample.
You need to make it follow this format:
authority: "https://contoso.b2clogin.com/contoso.onmicrosoft.com/Your-B2C-SignInOrSignUp-Policy-Id"
As follows:
const AuthorityUrl = https://${tenantName}.b2clogin.com/tfp/${tenantName}.onmicrosoft.com/${signInPolicy}

Wrong version of access token (expect V2 , received V1)

I am trying to register users from the Azure Active directory using #azure/msal-angular, to be more precise I tried the following tutorial
Those are the changes I have made to the project
export function MSALInstanceFactory(): IPublicClientApplication {
return new PublicClientApplication({
auth: {
clientId: 'my_real_client_id,
redirectUri: 'http://localhost:4200',
authority: 'https://login.microsoftonline.com/my_real_tenant_id',
postLogoutRedirectUri: '/'
},
cache: {
cacheLocation: BrowserCacheLocation.LocalStorage,
storeAuthStateInCookie: isIE, // set to true for IE 11
},
system: {
loggerOptions: {
loggerCallback,
logLevel: LogLevel.Info,
piiLoggingEnabled: false
}
}
});
}
export function MSALInterceptorConfigFactory(): MsalInterceptorConfiguration {
const protectedResourceMap = new Map<string, Array<string>>();
protectedResourceMap.set('https://graph.microsoft.com/v1.0/me', ['user.read']);
protectedResourceMap.set('http://localhost:5000/', ['profile']);
return {
interactionType: InteractionType.Redirect,
protectedResourceMap
};
}
The problem is that MsalInterceptor adds V1 token to the URL for the request to my API which expects V2.
Azure is configured to accessTokenAcceptedVersion: 2
I can provide more information if needed
Update
In my case, the problem was due to the scopes specified, both API for "user.read" and "profile" require V1 accessToken
Although you have resolved the issue, I would like to clarify more details.
In fact it's not the permissions "user.read" and "profile" require V1 accessToken. The actual reason is that:
Access Tokens versions are determined by the configuration of your application/API in the manifest. You have to change the accessTokenAcceptedVersion part of the manifest to 2 if you want a V2 access token. This is also the reason why you cannot control what version of the access token you will get from your client application when you request an access token.
We can't modify the accessTokenAcceptedVersion from Microsoft Graph side.
So the conclusion is that an access token for MS Graph and those are always V1 access token.

How to get user profile details using Azure AD

I am using react-aad-masl module to integrate Microsoft SSO in my react application. I am able to redirect my user to Microsoft login page and after that its coming back to my page with token. After that its only returning accountInfo that contain User name and email ID. I have a requirement to get user other details as well like ID, first name, last name, Group, etc.
These all details will come through this Azure AD MASL or i need to do Graph API call?
Below is my implementation
//authProvider.js
import { MsalAuthProvider, LoginType } from 'react-aad-msal';
import { Logger, LogLevel } from "msal";
// Msal Configurations
const config = {
auth: {
authority: 'https://login.microsoftonline.com/*********',
clientId: '*************',
redirectUri: 'http://localhost:3000/'
},
// Enable logging of MSAL events for easier troubleshooting.
// This should be disabled in production builds.
system: {
logger: new Logger(
(logLevel, message, containsPii) => {
console.log("[MSAL]", message);
},
{
level: LogLevel.Verbose,
piiLoggingEnabled: false
}
)
},
cache: {
cacheLocation: "sessionStorage",
storeAuthStateInCookie: true
}
};
// Authentication Parameters
const authenticationParameters = {
scopes: [
'user.read',
'profile',
'openid'
//'profile.read',
// 'User.Read.All',
// 'Group.Read.All',
// 'User.ReadBasic.All',
// 'Group.Read'
]
}
// Options
const options = {
loginType: LoginType.Redirect,
tokenRefreshUri: window.location.origin + '/auth.html'
}
export const authProvider = new MsalAuthProvider(config, authenticationParameters, options)
//APP.js
<AzureAD provider={authProvider} forceLogin={false}>
{(abc) => {
console.log('>>>>>>>>>>>>...', abc);
props.setAccountInfo(abc.accountInfo.account);
return <AppRouter />
}}
</AzureAD>
Here in abc i am getting below information
Please help me in this
You need to configure the optional claims in the application token configuration for First Name, Last Name.
Please go through the documentation for more information
Regarding the group information please check this document

Resources