-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Problem Using Identity Web with Blazor Server Client App #442
Comments
@DigitalPZ, Can you please verify if the method where you catch exception and handle consent have AuthorizeForScopes attribute? |
I did not have the AuthorizeForScopes attribute on that method but I have now added it based on the server tutorial you linked to above and I still get the authentication looping_. |
Can you check if you have added API permissions in Blazor server app on Azure portal? |
The Blazor server app is registered as per the instructions as is the API app. The Blazor app has the extra item in appsettings for the client secret. I also made sure that the app registration for the Blazor app was given API permissions to the API scope that was registered. I have the Fiddler trace. What config files do you need and where can I send it all to? |
Contact to share fiddler trace: v-lnushama At microsoft.com |
Email sent |
Shama, is the v- part of your email address? The email I sent you was rejected as address not found. |
yes, it's "v-lnushama". |
I resent it, I thought the l was a capital i. |
@DigitalPZ, Could you please check Startup.cs in your project and see if scope is passed in EnableTokenAcquisitionToCallDownstreamApi. Here is the code for your reference Startup.cs. |
I checked and I was not passing the scope in there. I was passing the scope in the GetAccessTokenForUserAsync call. I left it in there and added it in the startup call. I revoked the admin consent in the portal and re-tested and it now works. Why does it need to be in both places? I left it out because I saw documentation that said you could leave it out of startup and ask for it when needed. |
Which documentation is this, @DigitalPZ ? |
Sorry I don't remember where I saw it, I went through so many different pieces of documentation trying to solve this. |
Hi, I have all the tooling (visual studio 2019) and nuget packages on the latest version. Startup.cs public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAd"))
.EnableTokenAcquisitionToCallDownstreamApi()
//.EnableTokenAcquisitionToCallDownstreamApi(new string[] { "api://HiddenGuid/User.Read" })
.AddInMemoryTokenCaches();
services.AddControllersWithViews()
.AddMicrosoftIdentityUI();
services.AddAuthorization(options =>
{
// By default, all incoming requests will be authorized according to the default policy
options.FallbackPolicy = options.DefaultPolicy;
});
services.AddBootstrapCss();
services.AddHttpClient();
services.AddRazorPages();
services.AddServerSideBlazor()
.AddMicrosoftIdentityConsentHandler();
services.AddTransient<UserService>();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapBlazorHub();
endpoints.MapFallbackToPage("/_Host");
});
} UserService.cs public async Task<User> GetCustomer(CustomerDetailsViewModel model, PrincipalSecurityContext securityContext)
{
var scopes = new string[] { "api://HiddenGuid/User.Read" };
await SetAuthorizationAsync(securityContext, scopes);
var request = new HttpRequestMessage(HttpMethod.Get, $"v1/customers/{model.Id}");
var response = await Client.SendAsync(request);
try
{
response.EnsureSuccessStatusCode();
return JsonSerializer.Deserialize<User>(await response.Content.ReadAsStringAsync(), options);
}
catch (HttpRequestException ex)
{
throw await HandleError(response, ex);
}
}
private async Task SetAuthorizationAsync(PrincipalSecurityContext securityContext, string[] scopes = null)
{
string accessToken = null;
switch (securityContext)
{
case PrincipalSecurityContext.UserRole:
throw new NotImplementedException("Unknown security context");
break;
case PrincipalSecurityContext.UserScope:
accessToken = await _tokenAcquisitionService.GetAccessTokenForUserAsync(scopes);
break;
case PrincipalSecurityContext.ApplicationRole:
accessToken = await _tokenAcquisitionService.GetAccessTokenForAppAsync("api://HiddenGuid/.default");
break;
default:
throw new NotImplementedException("Unknown security context");
}
Client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
} CustomerDetails.razor
If I call the above code (with SecurityContext PrincipalSecurityContext.UserScope. So accessToken = await _tokenAcquisitionService.GetAccessTokenForUserAsync(scopes);), I get a correct In my test app, I of course have the permissions correctly. Working code as workaround @DigitalPZ You say "Consent is asked for and given". So you see a redirect to Azure AD consent page???? I don't see that happen.... |
That's the whole idea behind the page Managing incremental consent and conditional access right? |
One thing extra... When I use the code: But when I then change the code to: So conclusion: |
@DigitalPZ and @LockTar, It's fixed, here is the related issue raised in Microsoft.Identity.Web. |
Hi @Shama-K, |
It will be available in 1.4.2 as mentioned in this issue. |
@Shama-K My issue about this is solved for me at least. Tested with version 1.5.1 of the Nuget package. |
@LockTar, Thank you for letting us know. |
This issue is for a: (mark with an
x
)The issue was found for the following scenario:
Please add an 'x' for the scenario(s) where you found an issue
Repro-ing the issue
Repro steps
Generate new Blazor Server app to use as client and Asp.Net Core Web API using the templates shipped with Visual Studio 16.8.2. Choose Authentication with work or school account in both cases. Add the client secret to the client app appsettings.json file and add code as prescribed in the wiki in this repo to enable token retrieval.
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAd")) .EnableTokenAcquisitionToCallDownstreamApi() .AddInMemoryTokenCaches();
Add additional consent handler code to Blazor page as per instructions found in this wiki.
` try
{
forecasts = await ForecastService.GetForecastAsync();
`
Retrieve token and call API with the following code:
string[] scopes = new[] { _config["API:Scope"] }; var token = await _tokenAcquisition.GetAccessTokenForUserAsync(scopes); _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token); _httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); var response = await _httpClient.GetAsync($"{_config["API:BaseAddress"] }/WeatherForecast");
Navigate to Blazor page that calls the service that calls the API.
Expected behavior
Get asked for consent
Get asked to login and provide credentials
API gets called
Actual behavior
Consent is asked for and given
Dialog pops up asking which work or school account to use and when I choose it, it loops back to the same dialog asking the same question. I placed a breakpoint on the controller method in the API and it is never reached.
Possible Solution
Additional context/ Error codes / Screenshots
Any log messages given by the failure
Add any other context about the problem here, such as logs.
OS and Version?
Versions
Attempting to troubleshooting yourself:
Mention any other details that might be useful
If I remove the [Authorize] attribute from the API controller the authentication loop does not occur.
The text was updated successfully, but these errors were encountered: