I created a new Blazor (Server-side) application with Windows Authentication and run it using IIS Express. It will display a message of "Hello Domain\User!" from the following razor component (...\BlazorApp1\BlazorApp1\Shared\LoginDisplay.razor
) on top right.
<AuthorizeView>
Hello, @context.User.Identity.Name!
</AuthorizeView>
If running using Kestrel, the message is not shown. So I tried the following steps to make it work in Kestrel.
Import NuGet package Microsoft.AspNetCore.Authentication.Negotiate
Add the following code in ConfigureService()
in Startup.cs
.
services.AddAuthentication(NegotiateDefaults.AuthenticationScheme).AddNegotiate();
Configure()
in Startup.cs
. They are added between app.UseRouting();
and app.UseEndpoints(...
; app.UseAuthentication();
app.UseAuthorization();
It still doesn't show the Hello message. And I read "Anonymous requests are allowed. Use ASP.NET Core Authorization to challenge anonymous requests for authentication." in the document, so I did the following to disable anonymous requests.
In _Host.cshtml
, added the following lines after @namespace BlazorApp1.Pages
.
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize]
However, the message is still not displayed? Does it mean the authorization is not working?
Update:
I updated the file ...\BlazorApp1\BlazorApp1\Shared\LoginDisplay.razor
to
<AuthorizeView>
<Authorized>
Hello, @context.User.Identity.Name!
</Authorized>
<NotAuthorized>
You are not authorized to view that page...
</NotAuthorized>
</AuthorizeView>
It shows "You are not authorized to view that page...". It seems the Windows Authentication is not working?
The following is mentioned in the doc.
Windows environment configuration The Microsoft.AspNetCore.Authentication.Negotiate component performs User Mode authentication. Service Principal Names (SPNs) must be added to the user account running the service, not the machine account. Execute
setspn -S HTTP/mysrevername.mydomain.com myuser
in an administrative command shell.
I tried to run the following command in Administrator powershell console on my personnel PC at home.
setspn -S HTTP/mypcname myusername
However, it got the error
PS C:\WINDOWS\system32> setspn -S HTTP/desktop8930 nkucw
Ldap Error(0x51 -- Server Down): ldap_connect
Failed to retrieve DN for domain "" : 0x00000051
Warning: No valid targets specified, reverting to current domain.
FindDomainForAccount: Call to DsGetDcNameWithAccountW failed with return value 0x0000054B
Unable to locate account nkucw
Here is the output: (It shows "Authorization was successful." a few times in the log, but the last showes Authorization failed)
info: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[0] User profile is available. Using 'C:\Users\nkucw\AppData\Local\ASP.NET\DataProtection-Keys' as key repository and Windows DPAPI to encrypt keys at rest. info: Microsoft.Hosting.Lifetime[0] Now listening on: https://localhost:5001 info: Microsoft.Hosting.Lifetime[0] Now listening on: http://localhost:5000 info: Microsoft.Hosting.Lifetime[0] Application started. Press Ctrl+C to shut down. info: Microsoft.Hosting.Lifetime[0] Hosting environment: Development info: Microsoft.Hosting.Lifetime[0] Content root path: C:\Users\nkucw**strong text**\source\repos\TestPS\BlazorApp1 info: Microsoft.AspNetCore.Hosting.Diagnostics[1] Request starting HTTP/1.1 GET https://localhost:5001/ info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2] Authorization failed. info: Microsoft.AspNetCore.Authentication.Negotiate.NegotiateHandler[12] AuthenticationScheme: Negotiate was challenged. info: Microsoft.AspNetCore.Hosting.Diagnostics[2] Request finished in 135.0172ms 401 info: Microsoft.AspNetCore.Hosting.Diagnostics[1] Request starting HTTP/1.1 GET https://localhost:5001/ info: Microsoft.AspNetCore.Authentication.Negotiate.NegotiateHandler[0] None info: Microsoft.AspNetCore.Authentication.Negotiate.NegotiateHandler[1] Incomplete Negotiate handshake, sending an additional 401 Negotiate challenge. info: Microsoft.AspNetCore.Hosting.Diagnostics[2] Request finished in 16.6473ms 401 info: Microsoft.AspNetCore.Hosting.Diagnostics[1] Request starting HTTP/1.1 GET https://localhost:5001/ info: Microsoft.AspNetCore.Authentication.Negotiate.NegotiateHandler[0] None info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[1] Authorization was successful. info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0] Executing endpoint '/_Host' info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[3] Route matched with {page = "/_Host"}. Executing page /_Host info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[103] Executing an implicit handler method - ModelState is Valid info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[104] Executed an implicit handler method, returned result Microsoft.AspNetCore.Mvc.RazorPages.PageResult. info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[1] Authorization was successful. info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[4] Executed page /_Host in 206.51090000000002ms info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1] Executed endpoint '/_Host' info: Microsoft.AspNetCore.Hosting.Diagnostics[2] Request finished in 270.6847ms 200 text/html; charset=utf-8 info: Microsoft.AspNetCore.Hosting.Diagnostics[1] Request starting HTTP/1.1 GET https://localhost:5001/css/bootstrap/bootstrap.min.css info: Microsoft.AspNetCore.Hosting.Diagnostics[1] Request starting HTTP/1.1 GET https://localhost:5001/css/site.css info: Microsoft.AspNetCore.Hosting.Diagnostics[1] Request starting HTTP/1.1 GET https://localhost:5001/_framework/blazor.server.js info: Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware[6] The file /css/site.css was not modified info: Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware[6] The file /_framework/blazor.server.js was not modified info: Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware[6] The file /css/bootstrap/bootstrap.min.css was not modified info: Microsoft.AspNetCore.Hosting.Diagnostics[2] Request finished in 26.105700000000002ms 304 text/css info: Microsoft.AspNetCore.Hosting.Diagnostics[2] Request finished in 21.6629ms 304 application/javascript info: Microsoft.AspNetCore.Hosting.Diagnostics[2] Request finished in 21.6629ms 304 text/css info: Microsoft.AspNetCore.Hosting.Diagnostics[1] Request starting HTTP/1.1 GET https://localhost:5001/css/open-iconic/font/css/open-iconic-bootstrap.min.css info: Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware[6] The file /css/open-iconic/font/css/open-iconic-bootstrap.min.css was not modified info: Microsoft.AspNetCore.Hosting.Diagnostics[2] Request finished in 7.1119ms 304 text/css info: Microsoft.AspNetCore.Hosting.Diagnostics[1] Request starting HTTP/1.1 POST https://localhost:5001/_blazor/negotiate text/plain;charset=UTF-8 0 info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0] Executing endpoint '/_blazor/negotiate' info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1] Executed endpoint '/_blazor/negotiate' info: Microsoft.AspNetCore.Hosting.Diagnostics[2] Request finished in 22.780900000000003ms 200 application/json info: Microsoft.AspNetCore.Hosting.Diagnostics[1] Request starting HTTP/1.1 GET https://localhost:5001/css/open-iconic/font/fonts/open-iconic.woff info: Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware[6] The file /css/open-iconic/font/fonts/open-iconic.woff was not modified info: Microsoft.AspNetCore.Hosting.Diagnostics[1] Request starting HTTP/1.1 GET https://localhost:5001/_blazor?id=ase9fodeUXavBCDTwk1Suw info: Microsoft.AspNetCore.Hosting.Diagnostics[2] Request finished in 7.676900000000001ms 304 application/font-woff info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0] Executing endpoint '/_blazor' info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2] Authorization failed.
Found out it works in Edge, but not in Chrome. Is it a bug of the server-side Blazor?
Even with Edge, keeping refreshing the page shows that it may not get the authentication sometimes.
Authentication. Negotiate NuGet package can be used with Kestrel to support Windows Authentication using Negotiate and Kerberos on Windows, Linux, and macOS. Credentials can be persisted across requests on a connection.
Integrated Windows Authentication (IWA) is a built-in Microsoft Internet Information Services (IIS) authentication protocol that can be used to automatically authenticate and sign-in a user to EMS Web App. IWA is best used on intranets where all clients accessing EMS Web App are within a single domain.
For . Start Visual Studio and select Create a new project. In the Create a new project dialog, select ASP.NET Core Web App (or Web API) > Next. In the Configure your new project dialog, enter Project name > Next. In the Additional Information dialog, select Authentication Type as Windows.
Windows authentication enables users to log in with their Windows credentials, using Kerberos or NTLM. The client sends credentials in the Authorization header. Windows authentication is best suited for an intranet environment.
I found your question while tackling a similar issue. I think I know the answer to your problem though - you can use a simple middleware which will challenge the authentication and display the login.
app.UseMiddleware<ValidateAuthentication>();
internal class ValidateAuthentication : IMiddleware
{
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
{
if (context.User.Identity.IsAuthenticated)
await next(context);
else
await context.ChallengeAsync();
}
}
services.AddSingleton<ValidateAuthentication>();
You should not need a constructor.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With