I am working on a single page application (SPA) app that grants access to specific paths in the application, based on roles setup in Azure AD for the user logging in. As per this https://github.com/Azure-Samples/ms-identity-javascript-react-tutorial/tree/main/5-AccessControl/1-call-api-roles
This is my authConfig file:
const clientId = window.REACT_APP_CLIENTID
export const msalConfig = {
auth: {
clientId: clientId,
authority: window.REACT_APP_AUTHORITY,
redirectUri: 'http://localhost:3000/todolist/', // You must register this URI on Azure Portal/App Registration. Defaults to window.location.origin
postLogoutRedirectUri: "/", // Indicates the page to navigate after logout.
navigateToLoginRequestUrl: false, // If "true", will navigate back to the original request location before processing the auth code response.
},
cache: {
cacheLocation: "sessionStorage", // Configures cache location. "sessionStorage" is more secure, but "localStorage" gives you SSO between tabs.
storeAuthStateInCookie: false, // 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;
}
}
}
}
};
/**
* Add here the endpoints and scopes when obtaining an access token for protected web APIs. 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 protectedResources = {
apiTodoList: {
todoListEndpoint: window.REACT_APP_APIENDPOINT+"/api/v2/support/list",
scopes: [window.REACT_APP_APIENDPOINT+"/access_as_user"],
},
}
/**
* 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://docs.microsoft.com/en-us/azure/active-directory/develop/v2-permissions-and-consent#openid-connect-scopes
*/
export const loginRequest = {
scopes: [...protectedResources.apiTodoList.scopes]
};
export const appRoles = {
TaskUser: "TaskUser",
TaskAdmin: "TaskAdmin",
TrialAdmin: "Trial.Admin",
GlobalAdmin: "Global.Admin"
}
You can see the authorization parameters (clientId, authority etc..) under 'auth'
Here is the App.jsx file (I believe there needs to be some change made here). You can see 'RouteGuard' that renders the Component {TodoList}, when the path 'todolist' is accessed.
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
import { MsalProvider } from "@azure/msal-react";
import { RouteGuard } from './components/RouteGuard';
import { PageLayout } from "./components/PageLayout";
import { TodoList } from "./pages/TodoList";
import { appRoles } from "./authConfig";
import "./styles/App.css";
const Pages = () => {
return (
<Switch>
<RouteGuard
exact
path='/todolist/'
roles={[appRoles.TaskUser, appRoles.TaskAdmin, appRoles.TrialAdmin, appRoles.GlobalAdmin]}
Component={TodoList}
/>
</Switch>
)
}
/**
* msal-react is built on the React context API and all parts of your app that require authentication must be
* wrapped in the MsalProvider component. You will first need to initialize an instance of PublicClientApplication
* then pass this to MsalProvider as a prop. All components underneath MsalProvider will have access to the
* PublicClientApplication instance via context as well as all hooks and components provided by msal-react. For more, visit:
* https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-react/docs/getting-started.md
*/
const App = ({ instance }) => {
return (
<Router>
<MsalProvider instance={instance}>
<PageLayout>
<Pages instance={instance} />
</PageLayout>
</MsalProvider>
</Router>
);
}
export default App;
And the 'Routeguard' component,
import React, { useState, useEffect } from "react"; import { Route } from "react-router-dom"; import { useMsal } from "@azure/msal-react";
export const RouteGuard = ({ Component, ...props }) => {
const { instance } = useMsal(); const [isAuthorized, setIsAuthorized] = useState(false); const onLoad = async () => { const currentAccount = instance.getActiveAccount(); if (currentAccount && currentAccount.idTokenClaims['roles']) { let intersection = props.roles .filter(role => currentAccount.idTokenClaims['roles'].includes(role)); if (intersection.length > 0) { setIsAuthorized(true); } } } useEffect(() => { onLoad(); }, [instance]); return ( <> { isAuthorized ? <Route {...props} render={routeProps => <Component {...routeProps} />} /> : <div className="data-area-div"> <h3>You are unauthorized to view this content.</h3> </div> } </> ); };
The issue I am facing here is in the authConfig file, the cacheLocation is 'LocalStorage' and I can see information stored there, like the clientId, authToken, realm, homeAccountId etc. I would want to control what is shown here, I can see important info shown here and I dont want to show it, while storage is still Local.
Any suggestions on how this can be done ? I dont want to use 'sessionStorage' - Thanks !