Update blazor templates with Microsoft.Identity.Web APIs
https://github.com/dotnet/aspnetcore/pull/24268
Remove accepted scope check for non-Identity.Web scenarios
https://github.com/dotnet/aspnetcore/pull/24894
Add Microsoft.Identity.Web migration guide to 3.1->5.0 documentation
https://github.com/dotnet/AspNetCore.Docs/issues/19810
Update Azure Active Directory documentation
https://github.com/dotnet/AspNetCore.Docs/issues/19809
⚠ Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.
@captainsafia ... I have a quick point of personal confusion here as I get into the updates. I decided to start with the small footprint coverage of Blazor Server docs. These will be quick to update, and I should have a PR up tomorrow morning.
According to John's cross-link to the AAD docs ...
Quickstart: Add sign-in with Microsoft to an ASP.NET Core web app
https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-v2-aspnet-core-webapp
... we're still setting "_Under Implicit grant, select ID tokens._" ... but I thought we were getting out of the business of implicit grant completely for 5.0 scenarios. My 5.0 Blazor Server with AAD test app won't run unless I provide it with implicit grant for id_token. With it, our coverage for passing tokens also works fine. Just wondering if you could clarify what I missed about dropping implicit grant ... i.e. ... was it only being dropped for client-side now (i.e., SPA platform configuration with Blazor WASM scenarios)?
I also note in passing that we should cross-link that AAD topic for Blazor Server. We don't carry Blazor Server content, which is good, but we also don't link to that Quickstart. In addition to that Web App quickstart cross-link, I'll also add a cross-link for ...
Quickstart: Protect an ASP.NET Core web API with Microsoft identity platform
https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-v2-aspnet-core-web-api
i.e. ... was it only being dropped for client-side now (i.e., SPA platform configuration with Blazor WASM scenarios)?
Correct. It's only being dropped for SPA-scenarios.
@captainsafia Hit a new one this morning ... it pertains to default scopes for a standalone Azure AD/MS accounts WASM app. I'll break it down into four questions.
For 3.x with a standalone WASM app, it wasn't necessary to specify a default scope. If the guidance is followed for a 5.x app without taking additional action, the app throws ...
ClientConfigurationError: empty_input_scopes_error: Scopes cannot be passed as null, undefined or empty array because they are required to obtain an access token.
... because there is no default in the framework ...
public IList<string> DefaultAccessTokenScopes { get; set; } = new List<string>();
Side note on the Auth Lib topic:
OidcProviderOptions has default scopes ...
public IList<string> DefaultScopes { get; } = new List<string> { "openid", "profile" };
... so what I'll do in the Auth Lib topic is mention that these two scopes are specified by default in the Access token scopes section of that topic.
So, I can give it an openid scope ...
options.ProviderOptions.DefaultAccessTokenScopes.Add("openid");
... and the app seems happy with that. Is that the right approach for the standalone guidance?
What about offline_access? Should the guidance also instruct specifying offline_access as an additional default scope? ... which seems right to me ...
options.ProviderOptions.DefaultAccessTokenScopes.Add("openid");
options.ProviderOptions.DefaultAccessTokenScopes.Add("offline_access");
... or should this one be additional? ... but this does not look right to me ...
options.ProviderOptions.DefaultAccessTokenScopes.Add("openid");
options.ProviderOptions.AdditionalScopesToConsent.Add("offline_access");
Then ... with one (or both) of those scopes :point_up: ... I wonder if even the 3.x documentation should be specifying those even though they aren't strictly required in a 3.x app. I don't think it would hurt anything to specify one (or both) in a 3.x app as a default instruction. If that's right, then I can provide the new guidance without having to version it for just 5.x.
Can u clarify the difference between adding scopes with DefaultAccessTokenScopes.Add and AdditionalScopesToConsent.Add?
The API remarks seem to say about the same thing. Can they be more specifically described?
Gets or set the list of default access tokens scopes to provision during the sign-in flow.
Gets or sets a list of additional scopes to consent during the initial sign-in flow.
If guidance can be more explicit, then I recommend that either you or I open an engineering issue to improve those API remarks. Let me know if you want me to open that issue if we end up saying something more specific in the docs.
So far, so good. :+1: I have today's initial updates ready to go on a local branch. After I get those questions ☝️ resolved in the content, I'll have the PR up later this afternoon. This PR will address:
Client and Server when referring to the projects created by the template, which will only be in English.After we get today's PR merged (hopefully by EOD 🤞), I'll pick up with the remainder of the hosted updates tomorrow morning on the next PR.
Question 1
@guardrex With regard to the default scopes issue, yes, we need this included in the Program.cs. It makes sense to extend it in this portion of the docs.
Question 2
We'll need to add the offline_access scope to support refresh tokens. It shouldn't matter but would recommend DefaultAccessTokenScopes to reduce concept count.
Question 3
I think keeping the setup for 3.x and modifying only 5.0 might reduce confusion, especially for folks who already have 3.x apps running.
Question 4
Behind the scenes, both default and additional scopes get propagated into the requests. The difference is largely a conceptual one, IMO. Default scopes for things like openid, email, profile, and offline_access and default API scopes for anything else and additional scopes for other values.
We use DefaultScopes in all our docs currently so we might want to continue with that pattern.
cc: @captainsafia ... I'll need one more day depending on working out this last scenario.
@jmprieur ...
UPDATE: Nevermind my previous rubber 🦆 post. I see now that I'd like to try a daemon app approach for the server API to call Graph API, and I've found those Azure docs and examples. I'll try this first given that I wasn't using an on-behalf-of approach to get the user's security groups in the current approach for this topic. I think that's what I'd like to try first. If that doesn't pan out for some reason, then I will proceed with the on-behalf-of call approach to Graph API and see how I can receive the groups and roles that way.
How much will .NET 5 and Identity Platform 2.0 influence the existing code people are writing with Blazor WASM on .NET Core 3.1, e.g. when using IdentityServer? @guardrex
@guardrex : are you looking for a Blazor Server app calling graph (it's done by the templates when writing:
dotnet new blazorserver --auth SingleOrg --calls-graph
And a sample is available from https://github.com/AzureAD/microsoft-identity-web/tree/master/tests/BlazorServerCallsGraph
or a Blazorwasm application?
dotnet new blazorwasm2 --auth SingleOrg --calls-graph --hosted)@jmprieur ... It's a server API of a hosted Blazor solution. The goal is for the server API to call Graph API after token verification (OnTokenValidated) to get the user's Azure security groups to make claims for policies that have been configured for the API's controllers. In the past, I was not using an on-behalf-of approach for the Graph API call. Instead, I was using an application (daemon) approach for the server API. The app was using the user's OID claim and had Directory.Read.All permission to make the call to memberOf. On Friday, I found the daemon docs+examples, so I was going to try that this morning. However ......
dotnet new blazorwasm2 --auth SingleOrg --calls-graph --hosted
That looks interesting ... I'll try that one. Thanks for the tip.
@ChristianWeyer ... I don't think there will be any changes. I haven't been informed of anything. I'll run an upgraded version of the existing IdS hosted test app with 5.0 to confirm.
@jmprieur .... I think that I'm on the right track now with this. My server API acting as a daemon app is now receiving back the user's Azure security groups and roles based on the user's OID claim in their access token and a call to https://graph.microsoft.com/v1.0/users/{oid}/memberOf, and that's what I was going for. :tada: Now, I should be able to establish claims for the user on that basis, thus the server API app's auth policies will be effective. Because this approach doesn't use an on-behalf-of paradigm for Graph API, it avoids having to grant a client scope for Directory.Read.All. Only the server API gets that scope. The user/client app has least privileged scopes for the server API ... they only get the registered API scope for the server API.
Let me qualify this approach tho at this DRAFT stage ... I'm not a security guru, and security is of great concern to me 😨. We will carefully review this before publishing anything. As I've explored the latest v2.0 docs and sample apps, it looks like user/client scopes for Graph API calls in server API apps are common. It might turn out that an on-behalf-of approach would be preferred here. I don't currently favor that approach for this example, but I'll be all :ear: on the PR to see if we need to do something different.
btw - WRT Blazor Server ... My current plan is to leave that to Azure docs and examples given that such apps should align with any ASP.NET Core app, but I need to take a closer look at what I can cross-link (e.g., along the line of what you posted :point_up:).
Thanks again for your help, @jmprieur ... it's always great to have your input! 🎷
thanks @guardrex
If you want to ITokenAcqusition directly, you have a method named GetTokenForAppAsync(), which will get you a token for your daemon app
If you want to use the GraphServiceClient, you'd want to read this GitHub issue: https://github.com/AzureAD/microsoft-identity-web/issues/654, which has additional code to make this work for a daemon scenario.
Feel free to send me your code/article to review;
_I got it!_ :tada:🎈:beers: ..... It just started working all the way through to claims and API access. I am able to use the Graph Service Client and with the acquired token. It seems happy with the setup.
Thanks ... I'll ping you on the PR within a few hours.