Title: ASP.NET Core Web API Windows Authentication
In this article, we will learn how to secure an ASP.NET Core Web API with Windows authentication. We will cover the following topics:
- What is Windows authentication?
- How to configure Windows authentication in ASP.NET Core
- How to protect endpoints with Windows authentication
- How to test Windows authentication
By the end of this article, you will be able to secure your ASP.NET Core Web API with Windows authentication and protect your endpoints from unauthorized access.
Header 1 | Header 2 | Header 3 |
---|---|---|
Data 1 | Data 2 | Data 3 |
Data 4 | Data 5 | Data 6 |
****
In this tutorial, you will learn how to enable Windows authentication in an ASP.NET Core web API. Windows authentication is a type of authentication that uses the Windows NTLM or Kerberos protocols to verify a user’s identity. It is a built-in feature of ASP.NET Core and does not require any additional configuration.
By the end of this tutorial, you will be able to:
- Enable Windows authentication in an ASP.NET Core web API
- Protect your API endpoints with Windows authentication
- Test your API with Windows authentication
**What is Windows Authentication?**
Windows authentication is a type of authentication that uses the Windows NTLM or Kerberos protocols to verify a user’s identity. It is a built-in feature of Windows operating systems and is used by many applications and services.
When a user attempts to access a Windows-authenticated resource, their browser will send a NTLM or Kerberos token to the server. The server will then use this token to verify the user’s identity. If the user is authenticated, they will be granted access to the resource.
Windows authentication is a secure authentication protocol that is widely used. However, it is not as secure as other authentication protocols, such as OAuth 2.0 or OpenID Connect. This is because Windows authentication does not require the user to provide a password.
**How to enable Windows Authentication in ASP.NET Core**
To enable Windows authentication in ASP.NET Core, you can use the following steps:
1. In your Startup.cs file, add the following using statements:
c
using Microsoft.AspNetCore.Authentication.WindowsAuthentication;
using Microsoft.AspNetCore.Authorization;
2. In your ConfigureServices method, add the following code:
c
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = WindowsAuthenticationDefaults.AuthenticationScheme;
});
services.AddAuthorization(options =>
{
options.AddPolicy(“RequireWindowsAuthentication”, policy =>
{
policy.RequireClaim(“WindowsAccountName”);
});
});
3. In your Configure method, add the following code:
c
app.UseAuthentication();
app.UseAuthorization();
4. Restart your application.
Now, when a user attempts to access your API, they will be prompted to authenticate with Windows. If they are authenticated, they will be granted access to the API.
Protecting your API endpoints with Windows authentication
You can protect your API endpoints with Windows authentication by using the [AuthorizeAttribute](https://docs.microsoft.com/en-us/aspnet/core/security/authorization/authorizeattribute?view=aspnetcore-6.0). For example, the following code will protect the `/api/products` endpoint with Windows authentication:
c
[Authorize(“RequireWindowsAuthentication”)]
public async Task GetProducts()
{
return Ok(new List());
}
When a user attempts to access the `/api/products` endpoint, they will be prompted to authenticate with Windows. If they are authenticated, they will be able to access the endpoint.
Testing your API with Windows authentication
You can test your API with Windows authentication by using the following steps:
1. Open a command prompt and run the following command:
cmd
net user testuser testpassword /add
This will create a new user account with the username `testuser` and the password `testpassword`.
2. Log in to your computer as the `testuser` account.
3. Open a browser and navigate to the URL of your API.
4. You should be prompted to authenticate with Windows. Enter the username `testuser` and the password `testpassword`.
5. If you are authenticated successfully, you will be able to access your API.
In this tutorial, you learned how to enable Windows authentication in an ASP.NET Core web API. You also learned how to protect your API endpoints with Windows authentication and how to test your API with Windows authentication.
By following these steps, you can secure your ASP.NET Core web API with Windows authentication.
ASP.NET Core Web API is a powerful framework for building RESTful APIs. It is designed to be lightweight and easy to use, and it can be used to create APIs for a variety of purposes, including internal applications, public-facing websites, and mobile applications.
Windows authentication is a security mechanism that is built into the Windows operating system. It allows you to restrict access to resources based on the user’s Windows account. This can be a very effective way to protect your API from unauthorized access.
In this tutorial, we will show you how to enable Windows authentication for an ASP.NET Core Web API. We will cover the following topics:
- Configuring Windows authentication in your application
- Authenticating users with Windows authentication
- Authorizing users to access resources
Configuring Windows Authentication
The first step is to configure Windows authentication in your application. To do this, you need to add the following middleware to the `Configure` method in your `Startup` class:
c
app.UseAuthentication();
This middleware will automatically authenticate users who are logged into Windows. If a user is not logged into Windows, they will be redirected to the login page.
Authenticating Users
Once you have configured Windows authentication, you need to authenticate users when they attempt to access protected resources. To do this, you can use the `HttpContext.User` property. This property provides access to the current user’s Windows account information.
For example, the following code snippet checks to see if the current user is an administrator:
c
if (HttpContext.User.IsInRole(“Administrator”)) {
// The current user is an administrator.
} else {
// The current user is not an administrator.
}
Authorizing Users
Once you have authenticated a user, you need to authorize them to access the resources that they requested. To do this, you can use the `Authorize` attribute. This attribute can be applied to controllers, actions, and methods.
For example, the following code snippet authorizes users to access the `GetProducts` action on the `ProductsController` controller:
c
[Authorize]
public async Task GetProducts() {
// Get the list of products.
var products = await _productService.GetProductsAsync();
// Return the list of products.
return Ok(products);
}
**
In this tutorial, we showed you how to enable Windows authentication for an ASP.NET Core Web API. We covered the following topics:
- Configuring Windows authentication in your application
- Authenticating users with Windows authentication
- Authorizing users to access resources
We hope that this tutorial has been helpful. For more information on ASP.NET Core Web API, please refer to the following resources:
- [ASP.NET Core Web API Documentation](https://docs.microsoft.com/aspnet/core/web-api/)
- [ASP.NET Core Web API Tutorials](https://docs.microsoft.com/aspnet/core/tutorials/web-api/)
- [ASP.NET Core Web API Samples](https://github.com/aspnet/samples/tree/master/aspnetcore/webapi)
Q: What is Windows authentication?
A: Windows authentication is a security mechanism that allows users to access resources on a Windows server by using their Windows credentials. When a user attempts to access a resource that is protected by Windows authentication, the server will authenticate the user by checking their username and password against the Active Directory database. If the user is authenticated, they will be granted access to the resource.
Q: How do I enable Windows authentication in ASP.NET Core Web API?
A: To enable Windows authentication in ASP.NET Core Web API, you can use the following steps:
1. In your Startup class, add the following middleware to the `ConfigureServices` method:
c
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = “Bearer”;
});
2. In your Startup class, add the following middleware to the `Configure` method:
c
app.UseAuthentication();
3. In your controller, add the following attribute to the action method that you want to protect:
c
[Authorize]
public async Task Get()
{
// Get the user from the context
var user = HttpContext.User;
// Return a response
return Ok(user);
}
Q: What are the benefits of using Windows authentication?
A: There are several benefits to using Windows authentication, including:
- Simplicity: Windows authentication is a simple and straightforward security mechanism to implement.
- Robustness: Windows authentication is a robust security mechanism that is well-tested and has been used for many years.
- Centralized management: Windows authentication can be centrally managed through Active Directory.
Q: What are the drawbacks of using Windows authentication?
A: There are a few drawbacks to using Windows authentication, including:
- Performance: Windows authentication can be more computationally expensive than other security mechanisms, such as token-based authentication.
- Limited cross-platform support: Windows authentication is only supported on Windows servers.
- Single sign-on: Windows authentication does not support single sign-on across multiple applications.
Q: What are some alternatives to Windows authentication?
There are a number of alternatives to Windows authentication, including:
- Token-based authentication: Token-based authentication is a security mechanism that uses tokens to authenticate users. Tokens are typically issued by a central authority and are used to access resources on different servers.
- OAuth 2.0: OAuth 2.0 is a popular authorization framework that can be used to implement token-based authentication.
- OpenID Connect: OpenID Connect is an identity layer built on top of OAuth 2.0. It provides additional features, such as user profile information and single sign-on.
Q: Which authentication mechanism should I use?
The best authentication mechanism for your application will depend on your specific requirements. If you need a simple and robust security mechanism that is well-supported, then Windows authentication is a good option. If you need a more performant or cross-platform solution, then you may want to consider an alternative authentication mechanism.
In this article, we have discussed how to implement Windows authentication in ASP.NET Core Web API. We first looked at the different authentication schemes available in ASP.NET Core and how to configure them. Then, we discussed how to implement Windows authentication using the `IdentityServer4` library. We also covered how to protect your API endpoints with Windows authentication and how to allow unauthenticated users to access some endpoints.
We hope that this article has been helpful and that you are now able to implement Windows authentication in your ASP.NET Core Web API applications.
Here are some key takeaways from this article:
- Windows authentication is a secure authentication scheme that can be used to protect your ASP.NET Core Web API applications.
- To implement Windows authentication, you can use the `IdentityServer4` library.
- You can protect your API endpoints with Windows authentication by using the `Authorize` attribute.
- You can allow unauthenticated users to access some endpoints by using the `AllowAnonymous` attribute.
Author Profile
-
Hatch, established in 2011 by Marcus Greenwood, has evolved significantly over the years. Marcus, a seasoned developer, brought a rich background in developing both B2B and consumer software for a diverse range of organizations, including hedge funds and web agencies.
Originally, Hatch was designed to seamlessly merge content management with social networking. We observed that social functionalities were often an afterthought in CMS-driven websites and set out to change that. Hatch was built to be inherently social, ensuring a fully integrated experience for users.
Now, Hatch embarks on a new chapter. While our past was rooted in bridging technical gaps and fostering open-source collaboration, our present and future are focused on unraveling mysteries and answering a myriad of questions. We have expanded our horizons to cover an extensive array of topics and inquiries, delving into the unknown and the unexplored.
Latest entries
Windows Authentication in ASP.NET Core
Last Modified: 2017-03-28
Using Windows Authentication in ASP.NET Core Web Applications
ASP.NET Core Windows Authentication
Note that some of the content does not apply to RC1 or earlier versions and may not apply to later versions either.
General
- https://docs.asp.net/en/latest/security/authentication/index.html
- https://blogs.msdn.microsoft.com/webdev/2016/03/11/first-look-authentication-in-asp-net-core/
- https://docs.asp.net/en/latest/fundamentals/servers.html
- https://docs.asp.net/en/latest/publishing/iis.html
- https://github.com/aspnet/Announcements/issues/204
Enable Windows Authentication
The server running the application must be configured to enable windows authentication and disable anonymous authentication.
If anonymous authentication is enabled, then it will be used by default and no user information is collected or required.
Hosting Options
- IIS + Kestrel: Windows authentication is configured in IIS (or
Properties\launchSettings.json
when debugging with Visual Studio and IIS Express). - WebListener: Windows authentication is configured in web host builder programmatically.
At the time of writing, windows authentication only works when the server is hosted on the Windows platform (IIS and WebListener are Windows-only).
Take a look at ASP.NET Core Hosting for setting up either hosting option.
Sources:
- https://docs.asp.net/en/latest/fundamentals/servers.html
WebListener
When using WebListener, you need to set up the authentication scheme in WebListener options in Program.cs
:
using System.IO;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Net.Http.Server;
public static void Main(string[] args)
{
var host = new WebHostBuilder()
.UseWebListener(options =>
{
options.ListenerSettings.Authentication.Schemes = AuthenticationSchemes.NTLM; // <--
options.ListenerSettings.Authentication.AllowAnonymous = false; // <--
})
.UseStartup<Startup>()
.Build();
host.Run();
}
Note: installing package Microsoft.Net.Http.Server
from NuGet is required for accessing the AuthenticationSchemes class.
Sources:
- https://github.com/aspnet/Announcements/issues/204
- http://stackoverflow.com/questions/37694211/windows-authentication-with-asp-net-core
IIS Integration
When using IIS Integration (Express or not), there are some configuration options that you can tweak.
Add configuration in Startup.cs
in the ConfigureServices
method:
services.Configure<IISOptions>(options => {
//options.AuthenticationDescriptions holds a list of allowed authentication schemes
options.AutomaticAuthentication = true;
options.ForwardClientCertificate = true;
options.ForwardWindowsAuthentication = true;
});
All three options default to true
at least when running on IIS Express through Visual Studio.
Source: https://docs.asp.net/en/latest/fundamentals/servers.html
IIS Express (when Debugging from Visual Studio)
In visual studio, right-click into the project properties and select the Debug tab.
Check “Enable Windows Authentication” and uncheck “Enable Anonymous Authentication”
The values are stored in Properties\launchSettings.json
:
{
"iisSettings": {
"windowsAuthentication": true,
"anonymousAuthentication": false,
...
},
...
}
Making this change also forces forwardWindowsAuthToken
to true
in web.config
(aspNetCore
-element under system.webServer
) each time you start the app in debug mode.
IIS
Enable windows authentication in IIS application host configuration file which can be found in the system32\inetsrv
directory.
NOTE: IIS Express application configuration file lives in $(solutionDir)\.vs\config\applicationhost.config
source when using Visual Studio 2015 (or %userprofile%\documents\iisexpress\config\applicationhost.config
or somewhere else when using an earlier version).
TODO not verified using IIS Express directly. The configuration does not affect the behaviour of IIS Express when debugging through Visual Studio.
The correct section can be found in configuration -> system.webServer -> security -> authentication -> windowsAuthentication.
The configuration should look as follows.
<windowsAuthentication enabled="true">
<providers>
<add value="Negotiate" />
<add value="NTLM" />
</providers>
</windowsAuthentication>
TODO May have to remove the Negotiate
provider as per http://stackoverflow.com/questions/36946304/using-windows-authentication-in-asp-net?
Windows authentication can also be enabled using the Internet Information Services Manager:
Go to the site’s Authentication settings, enable Windows Authentication and disable Anonymous Authentication.
Make sure that the forwardWindowsAuthToken
is set to true
in web.config
(aspNetCore
-element under system.webServer
).
Sources:
- https://docs.asp.net/en/latest/publishing/iis.html
- http://www.codeproject.com/Tips/1022870/AngularJS-Web-API-Active-Directory-Security
- http://stackoverflow.com/questions/4762538/iis-express-windows-authentication
- http://stackoverflow.com/questions/36946304/using-windows-authentication-in-asp-net
- http://www.danesparza.net/2014/09/using-windows-authentication-with-iisexpress/
Identity Impersonation
TODO For accessing further resources such as an SQL DB or other APIs with windows authentication.
Sources:
- http://stackoverflow.com/questions/35180871/asp-net-core-1-0-impersonation
- https://aleksandarsimic.wordpress.com/2016/07/21/asp-net-core-1-0-iis-impersonation/
Accessing User Information
CSHtml
You can access user identity in .cshtml
files by using, for example:
<pre>@Html.Raw(Json.Serialize(User, new Newtonsoft.Json.JsonSerializerSettings() { ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore }))</pre>
<p>Name: @User.Identity.Name</p>
<p>Authenticated: @User.Identity.IsAuthenticated</p>
If you need to access the HttpContext, you need to add the HttpContextAccessor service in Startup.cs
:
public void ConfigureServices(IServiceCollection services)
{
...
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
...
}
And in cshtml:
@inject IHttpContextAccessor httpContextaccessor
<pre>@Html.Raw(Json.Serialize(HttpContextAccessor.HttpContext.User.Identity, new Newtonsoft.Json.JsonSerializerSettings() { ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore }))</pre>
Source: http://stackoverflow.com/questions/38945678/access-cookie-in-layout-cshtml-in-asp-net-core
In MCV or WebAPI Controllers
var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
var userName = User.FindFirstValue(ClaimTypes.Name);
var userName2 = User.Identity.Name;
Requires package Microsoft.AspNetCore.Identity
Sources:
- http://stackoverflow.com/questions/30701006/how-to-get-the-current-logged-in-user-id-asp-net-core
JavaScript
There is no way that I came across to get at the windows user information directly in JavaScript, except by injecting through script tags and cshtml.
Source: http://stackoverflow.com/questions/3013692/getting-windows-username-with-javascript
Calling API Methods from JavaScript
Make sure you include credentials in calls, e.g. with fetch
:
fetch("/api/SampleData/WeatherForecasts", { credentials: 'include' })
.then(response => { ... });
Local groups:
- Local groups are written without the domain part or prefixed with the host name:
<group>
or<hostname>\<group>
. - Built-in local groups (e.g.
BUILTIN\Administrators
) are not recognized by name.
You have to write the corresponding SID instead. - You can find out the SIDs by using the
PsGetSid
tool: https://technet.microsoft.com/en-us/sysinternals/bb897417. - The
BUILTIN\Administrators
group is not recognized even when using the correct SID.
Group membership shows as role membership in ASP.NET Core.
You can enforce group membership directly with the Authorize attribute, with an authorization policy, or programmatically in the controller methods.
Authorize Attribute
Add [Authorize(Roles = @"<domain>\<group>")]
attribute (or [Authorize(Roles = @"<domain>\<group1>,<domain>\<group2>")]
for multiple allowed roles) to the controller or method.
Sources:
- https://docs.asp.net/en/latest/security/authorization/roles.html
Authorization Policy
Add a new policy to service configuration in ConfigureServices
method in Startup.cs
:
services.AddAuthorization(options =>
{
options.AddPolicy("RequireWindowsGroupMembership", policy => policy.RequireRole(@"<domain>\<group>"));
});
To get the required group name from settings, add the group name into appsettings.json
(note the double backslashes):
{
"Logging": {
...
},
"WindowsGroup": "<domain>\\<group>"
}
Then read it in when configuring authorization:
services.AddAuthorization(options =>
{
var windowsGroup = Configuration.GetValue<string>("WindowsGroup");
options.AddPolicy("RequireWindowsGroupMembership", policy =>
{
policy.RequireAuthenticatedUser(); // Policy must have at least one requirement
if (windowsGroup != null)
policy.RequireRole(windowsGroup);
});
});
Use a comma-separated string for multiple allowed roles: <domain>\<group1>,<domain>\<group2>
.
Finally, add the authorize-attribute on the controller or method: [Authorize(Policy = "RequireWindowsGroupMembership")]
Sources:
- https://docs.asp.net/en/latest/security/authorization/roles.html
The policy syntax allows for more elaborate authorization scenarios with custom requirements, such as activity/permission-based authentication
- https://docs.asp.net/en/latest/security/authorization/policies.html
- https://lostechies.com/derickbailey/2011/05/24/dont-do-role-based-authorization-checks-do-activity-based-checks/
- http://benjamincollins.com/blog/practical-permission-based-authorization-in-asp-net-core/
- http://benfoster.io/blog/asp-net-identity-role-claims
Programmatically
Check for role membership in controller method and return 403 Forbidden status code if not authorized.
[HttpGet("[action]")]
public IActionResult SomeValue()
{
if (!User.IsInRole(@"Domain\Group")) return StatusCode(403);
return Ok("Some Value");
}
Note that the return type of the method must be IActionResult
.
Browser Settings
If you need automatic windows authentication, then you may have to enable it specifically in the client browser
- IE (TODO verify same works in EDGE)
- Advanced -> Enable Integrated Windows Authentication in Internet Options
- Security -> Local intranet -> Custom level -> User Authentication -> Automatic logon / Prompt for user name and password
- Chrome
- Chrome uses settings in Windows’ internet options so the IE options should sufficesource
- Firefox
- about:config -> network.automatic-ntlm-auth.trusted-uris -> add url of application
Sources:
- http://www.codeproject.com/Tips/1022870/AngularJS-Web-API-Active-Directory-Security
- http://stackoverflow.com/questions/36946304/using-windows-authentication-in-asp-net
Different Domain or No Domain Binding
TODO I did not get this to work from a remote site, with or without VPN connection (flashes a new console window and dies instantly, unable to capture error message)
If you are developing on a computer that is not bound to a domain, or is bound to a different domain that the app should authenticate against, you can run the server like so:
runas /netonly /user:<user> "<command> <args...>"
where <user>
is domain\username
or username@domain
.
IIS: you must establish trust between the two domains to be able to run app pools under a user in different domain than the server.
IIS: does this work at all when running as network service??
Sources:
- http://codebetter.com/jameskovacs/2009/10/12/tip-how-to-run-programs-as-a-domain-user-from-a-non-domain-computer/
- http://stackoverflow.com/questions/4762538/iis-express-windows-authentication
- http://stackoverflow.com/questions/5331206/how-to-run-iisexpress-app-pool-under-a-different-identity
- http://stackoverflow.com/questions/22058645/authenticate-against-a-domain-using-a-specific-machine/22060458#22060458
- https://forums.iis.net/t/1213147.aspx?How+I+can+run+IIS+app+pool+by+domain+account+
- https://blogs.msdn.microsoft.com/ssehgal/2009/06/23/running-iis6-app-pools-under-a-domain-account-identity/
This article shows how authorization could be implemented for an ASP.NET Core MVC application. The authorization logic is extracted into a separate project, which is required by some certification software requirements. This could also be deployed as a separate service.
Code: https://github.com/damienbod/AspNetCoreWindowsAuth
Blogs in this series:
- Supporting both Local and Windows Authentication in ASP.NET Core MVC using IdentityServer4
- ASP.NET Core Authorization for Windows, Local accounts
History
2020-08-23 Updated to .NET Core 3.1, IdentityServer4 V4
2019-09-12 Updated to .NET Core 3.0
Application Authorization Service
The authorization service uses the claims returned for the identity of the MVC application. The claims are returned from the ASP.NET Core MVC client app which authenticates using the OpenID Connect Hybrid flow. The values are then used to create or define the authorization logic.
The authorization service supports a single API method, IsAdmin. This method checks if the username is a defined admin, and that the person/client used a Windows account to login.
using System; namespace AppAuthorizationService { public class AppAuthorizationService : IAppAuthorizationService { public bool IsAdmin(string username, string providerClaimValue) { return RulesAdmin.IsAdmin(username, providerClaimValue); } } }
The rules define the authorization process. This is just a simple static configuration class, but any database, configuration files, authorization API could be used to check, define the rules.
In this example, the administrators are defined in the class, and the Windows value is checked for the claim parameter.
using System; using System.Collections.Generic; using System.Text; namespace AppAuthorizationService { public static class RulesAdmin { private static List<string> adminUsers = new List<string>(); private static List<string> adminProviders = new List<string>(); public static bool IsAdmin(string username, string providerClaimValue) { if(adminUsers.Count == 0) { AddAllowedUsers(); AddAllowedProviders(); } if (adminUsers.Contains(username) && adminProviders.Contains(providerClaimValue)) { return true; } return false; } private static void AddAllowedUsers() { adminUsers.Add("SWISSANGULAR\\Damien"); } private static void AddAllowedProviders() { adminProviders.Add("Windows"); } } }
ASP.NET Core Policies
The application authorization service also defines the ASP.NET Core policies which can be used by the client application. An IAuthorizationRequirement is implemented.
using Microsoft.AspNetCore.Authorization; namespace AppAuthorizationService { public class IsAdminRequirement : IAuthorizationRequirement{} }
The IAuthorizationRequirement implementation is then used in the AuthorizationHandler implementation IsAdminHandler. This handler checks, validates the claims, using the IAppAuthorizationService service.
using Microsoft.AspNetCore.Authorization; using System; using System.Linq; using System.Threading.Tasks; namespace AppAuthorizationService { public class IsAdminHandler : AuthorizationHandler<IsAdminRequirement> { private IAppAuthorizationService _appAuthorizationService; public IsAdminHandler(IAppAuthorizationService appAuthorizationService) { _appAuthorizationService = appAuthorizationService; } protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, IsAdminRequirement requirement) { if (context == null) throw new ArgumentNullException(nameof(context)); if (requirement == null) throw new ArgumentNullException(nameof(requirement)); var claimIdentityprovider = context.User.Claims.FirstOrDefault(t => t.Type == "http://schemas.microsoft.com/identity/claims/identityprovider"); if (claimIdentityprovider != null && _appAuthorizationService.IsAdmin(context.User.Identity.Name, claimIdentityprovider.Value)) { context.Succeed(requirement); } return Task.CompletedTask; } } }
As an example, a second policy is also defined, which checks that the http://schemas.microsoft.com/identity/claims/identityprovider claim has a Windows value.
using Microsoft.AspNetCore.Authorization; namespace AppAuthorizationService { public static class MyPolicies { private static AuthorizationPolicy requireWindowsProviderPolicy; public static AuthorizationPolicy GetRequireWindowsProviderPolicy() { if (requireWindowsProviderPolicy != null) return requireWindowsProviderPolicy; requireWindowsProviderPolicy = new AuthorizationPolicyBuilder() .RequireClaim("http://schemas.microsoft.com/identity/claims/identityprovider", "Windows") .Build(); return requireWindowsProviderPolicy; } } }
Using the Authorization Service and Policies
The Authorization can then be used, by adding the services to the Startup of the client application.
services.AddSingleton<IAppAuthorizationService, AppAuthorizationService.AppAuthorizationService>(); services.AddSingleton<IAuthorizationHandler, IsAdminHandler>(); services.AddAuthorization(options => { options.AddPolicy("RequireWindowsProviderPolicy", MyPolicies.GetRequireWindowsProviderPolicy()); options.AddPolicy("IsAdminRequirementPolicy", policyIsAdminRequirement => { policyIsAdminRequirement.Requirements.Add(new IsAdminRequirement()); }); });
The policies can then be used in a controller and validate that the IsAdminRequirementPolicy is fulfilled.
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; namespace MvcHybridClient.Controllers { [Authorize(Policy = "IsAdminRequirementPolicy")] public class AdminController : Controller { public IActionResult Index() { return View(); } } }
Or the IAppAuthorizationService can be used directly if you wish to mix authorization within a controller.
private IAppAuthorizationService _appAuthorizationService; public HomeController(IAppAuthorizationService appAuthorizationService) { _appAuthorizationService = appAuthorizationService; } public IActionResult Index() { // Windows or local => claim http://schemas.microsoft.com/identity/claims/identityprovider var claimIdentityprovider = User.Claims.FirstOrDefault(t => t.Type == "http://schemas.microsoft.com/identity/claims/identityprovider"); if (claimIdentityprovider != null && _appAuthorizationService.IsAdmin( User.Identity.Name, claimIdentityprovider.Value) ) { // yes, this is an admin Console.WriteLine("This is an admin, we can do some specific admin logic!"); } return View(); }
If an admin user from Windows logged in, the admin view can be accessed.
Or the local guest user only sees the home view.
Notes:
This is a good way of separating the authorization logic from the business application in your software. Some certified software processes, require that the application authorization, authentication is audited before each release, for each new deployment if anything changed.
By separating the logic, you can deploy, update the business application without doing a security audit. The authorization process could also be deployed to a separate process if required.
Links:
https://docs.microsoft.com/en-us/aspnet/core/security/authorization/views?view=aspnetcore-2.1&tabs=aspnetcore2x
https://docs.microsoft.com/en-us/aspnet/core/security/authentication/?view=aspnetcore-2.1
https://mva.microsoft.com/en-US/training-courses/introduction-to-identityserver-for-aspnet-core-17945
https://stackoverflow.com/questions/34951713/aspnet5-windows-authentication-get-group-name-from-claims/34955119
https://github.com/IdentityServer/IdentityServer4.Templates
https://docs.microsoft.com/en-us/iis/configuration/system.webserver/security/authentication/windowsauthentication/
Tags: ASP.NET Core, aspnetcore, Authentication, Authorization, ID4, IdentityServer4, MVC, OAuth2, OIDC, OpenId, OpenId connect
Don’t let AI Agents fail in production
Restack backend framework provides long-running workflows and infrastructure for reliable & accurate AI agents.
Get started with example agents
Research Paper
Agent accuracy benchmark
Many enterprises are exploring AI agents, but one issue blocks their adoption: keeping them accurate and on brand. General-purpose LLMs hit only 51% accuracy, while fine-tuned small agents reach 99.7%.
The trust in AI is eroding due to unreliable, poorly designed agents. For AI to reach its full potential, we need better ones. Restack helps you build agents that are reliable, scalable, and ready for real-world use.
Features
The Restack framework
Build reliable and accurate AI agents with Restack.
Developer UI
Simulate, time travel and replay AI agents
The Restack developer toolkit provides a UI to visualize and replay workflows or individual steps. Open a favourite IDE like VS Code or Cursor on one side and view workflows on the other to improve debugging and local development.
Get started in seconds
Start building with Restack AI framework and deploy with Restack Cloud.
How to use Windows Authentication for ASP.NET Core Web APIs? We will try to do something like that in today’s tutorial using Min APIs.
First, create a new empty asp.net web project using the below command:
dotnet new web -o minwinauth
Then, switch to the minwinauth
folder and add Negotiate
package to the project since Windows Authentication requires the library:
dotnet add package Microsoft.AspNetCore.Authentication.Negotiate
Open your project using VS Code / any of your favourite IDE and paste the code below to the Program.cs
:
using Microsoft.AspNetCore.Authentication.Negotiate; using Microsoft.AspNetCore.Authorization; var builder = WebApplication.CreateBuilder(args); // Add services to the container. // To have Windows Authentication, we need to add NegotiateDefaults.AuthenticationScheme builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme).AddNegotiate(); builder.Services.AddAuthorization(); var app = builder.Build(); // Configure the HTTP request pipeline. app.UseAuthentication(); app.UseAuthorization(); app.MapGet("/", () => "Hello World!"); // Authorize attribute make the API needs authentication, and Negotiate... is for Windows Authentication. app.MapGet("/admin", [Authorize(AuthenticationSchemes = NegotiateDefaults.AuthenticationScheme)] (HttpContext context) => "The /admin endpoint is for authorizers only. User ID: " + context.User.Identity?.Name); app.Run();
Run the project using the command below:
dotnet run
If you browse the site, you will get “Hello World!” without you keying in any credential due to root directory is don’t need authentication. But if you browse /admin, a login dialog box will appear, and you need to key in the Windows credential.
If you click cancel or key in a wrong credential, you will get 401 Unauthorized with authentication method is Negotiate.
But if you key in correct Windows credential, you will able to login and see the message like below:
The /admin endpoint is for authorizers only. User ID: xxx/yyy
PS:
Please note this working in Windows environment only, if you try in Linux environment, you most probably will get 401 unauthorized due to no authentication can be made. If you want Linux to support this Windows Authentication, you need to setup the Linux environment configuration as stated in ASP.NET Core documentation https://docs.microsoft.com/en-us/aspnet/core/security/authentication/windowsauth?view=aspnetcore-6.0&tabs=visual-studio