My goal is to allow users to freely browse an Angular 11+ site, reading data called from a .NET Web API as they navigate. Only users who wish to post data or access particular features would need to sign up and sign in, using AD B2C identity services. Accordingly, controllers in the backend app service are marked with [Authorize] or [AllowAnonymous] as appropriate.
The site successfully supports browsing and posting for signed-in users, copying the approach from the AzureAD sample.
export function MSALInterceptorConfigFactory(): MsalInterceptorConfiguration {
const protectedResourceMap = new Map<string, Array<string>>();
protectedResourceMap.set(apiConfig.uri, apiConfig.scopes);
return {
interactionType: InteractionType.Redirect,
protectedResourceMap
};
}
However, using that approach, the Msal's httpInterceptor evidently fires for every database call, forcing a B2C signup/login event on all endpoints, defeating the effort to support anonymous browsing.
MSAL v1 apparently supported an unprotectedResource array, but that was deprecated for v2. It also apparently supported the use of null patterns such as
const resourceMap: [string, string[]][] = [
[`${apiBaseUrl}/health`, null],
[`${apiBaseUrl}`, ['scope1', 'scope2']],
];
Since that v1 object has a different shape I tried it this way in v2, but to no avail
const protectedResourceMap = new Map<string, Array<string>>();
protectedResourceMap.set(apiConfig.uri + '/myreadabledata', []);
protectedResourceMap.set(apiConfig.uri, apiConfig.scopes);
I've tried other approaches such as setting the protectedResourceMap exclusively for the controllers that require authorization. That failed as well.
const protectedResourceMap = new Map<string, Array<string>>();
protectedResourceMap.set(apiConfig.uri + '/mycloseddata1' , apiConfig.scopes);
protectedResourceMap.set(apiConfig.uri + '/mycloseddata2' , apiConfig.scopes);
What is the correct way to achieve this?
I ran into this same issue of wanting some api routes to be anonymous and not trigger a redirect to login. Managed to come across this link.
It looks like you were really close with what you tried. Translating what I did I believe you can use the following
From reading the code the trick looks to be to put your unprotected path(s) first and have it return a scope of
null
.I'm running
2.0.0-beta.5
and this works for me when callingGET uri/myreadabledata/{id}