Issue
I have succesfully implemented AAD authentication in my Ionic React Capacitor application. When I run the application in web by running ionic serve
it works flawlessly.
But when run the application on Android and when I press the login button I won't get redirected to the application and none of the credentials get set.
I get that the redirectUri given in the screenshot below is not correct and only works when running in web but I've tried using redirect uri's for 'Mobile and Desktop applications' and 'Android' platforms in azure active directory and I also could not get that working.
I've tried using several different redirect uri's and expected one of them to actually redirect back to the application.
I've tried using an In App Browser but I could not get the msal instance loginRedirect function to open in the In App Browser.
Solution
I have solved this issue by using the InAppBrowser plugin from Cordova (@awesome-cordova-plugins/in-app-browser) in combination with a custom implementation of the NavigationClient from msal (@azure/msal-browser).
The implementation looks like this:
import { InAppBrowser } from "@awesome-cordova-plugins/in-app-browser";
import type { IPublicClientApplication } from "@azure/msal-browser";
import { NavigationClient } from "@azure/msal-browser";
import { Capacitor } from "@capacitor/core";
export class NavigationAuthenticationClient extends NavigationClient {
constructor(private msalInstance: IPublicClientApplication) {
super();
}
async navigateExternal(url: string, options: any): Promise<boolean> {
if (Capacitor.isNativePlatform()) {
const browser = InAppBrowser.create(url, "_blank", {
location: "yes",
hidenavigationbuttons: "yes",
clearcache: "yes",
clearsessioncache: "yes",
hideurlbar: "yes",
fullscreen: "yes",
});
browser.on("loadstart").subscribe((event: any) => {
if (event.url.includes("#code")) {
browser.close();
const domain = event.url.split("#")[0];
const url = event.url.replace(domain, "http://localhost/home");
this.msalInstance
.handleRedirectPromise(url)
.then((res) => {
console.log(res?.account?.name + " has authenticated");
})
.catch((err) => {
console.log(err);
});
}
});
} else {
if (options.noHistory) {
window.location.replace(url);
} else {
window.location.assign(url);
}
}
return true;
}
}
I have extended the code of my LoginButton by first setting the new custom NavigationClient in the msal instance:
import { useMsal } from "@azure/msal-react";
import { IonFabButton, IonIcon } from "@ionic/react";
import { personOutline } from "ionicons/icons";
import { useEffect } from "react";
import { NavigationAuthenticationClient } from "../NavigationAuthenticationClient";
const LoginButton: React.FC = (): JSX.Element => {
const { instance } = useMsal();
useEffect(() => {
instance.setNavigationClient(new NavigationAuthenticationClient(instance));
}, []);
const handleSignIn = async () => {
await instance.loginRedirect({
scopes: ["..."],
});
};
return (
<IonFabButton onClick={handleSignIn} id="navigation_button">
<IonIcon size="small" icon={personOutline}></IonIcon>
</IonFabButton>
);
};
export default LoginButton;
Answered By - Ruben
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.