Ensure SSL is used by the application: https://learn.microsoft.com/en-us/aspnet/core/security/enforcing-ssl
identity
ASP.NET Core Identity (built in) has support for local user accounts and external identity providers. (An external option is [Identity Server (github.com)(https://github.com/IdentityServer/IdentityServer4)])
ASP.NET Core Identity is included in projects if Individual Accounts is selected.
configuring identity
In Program.cs
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.AddRazorPages();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseMigrationsEndPoint();
}
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.MapRazorPages();
app.Run();
in app startup
// Add framework services.
builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
builder.Services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
builder.Services.AddMvc();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseMigrationsEndPoint();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.MapRazorPages();
authentication
Schemes are techniques for performing authentication in web applications. DefaultAuthenticateScheme
is configured to provide a default scheme.
Calling AddIdentity<TUser, TRole>
also includes this call to configure the authentication scheme for a web app with user interaction:
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = IdentityConstants.ApplicationScheme;
options.DefaultChallengeScheme = IdentityConstants.ApplicationScheme;
options.DefaultSignInScheme = IdentityConstants.ExternalScheme;
});
The above schemes use cookies for persistence and redirection to login pages for authentication by default.
For a web API, configure authentication like this:
builder.Services
.AddAuthentication(config => { config.DefaultScheme = JwtBearerDefaults.AuthenticationScheme; })
.AddJwtBearer(config =>
{
config.RequireHttpsMetadata = false;
config.SaveToken = true;
config.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = false,
ValidateAudience = false
};
});
authentication in blazor apps
Blazor Server apps can use the same features as above.
Blazor WASM apps cannot use built-in Identity and Authentication providers since they run in a browser. They store user authentication status locally and access claims to determine authorization. All A&A checks should be performed on the server regardless of any logic implemented by the WASM app.
authorization
The Authorize attribute, along with roles, can be used:
[Authorize(Roles = "HRManager,Finance")] // This means either HRManager OR Finance. For AND, apply each role on individua lines.
public class SalaryController : Controller
{
}
Or, apply authorization policies instead of roles:
[Authorize(Policy = "CanViewPrivateReport")]
public IActionResult ExecutiveSalaryReport()
{
return View();
}
claims
Name-value pairs that represent properties of an authenticated user. Used as part of authorization policies:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddAuthorization(options =>
{
options.AddPolicy(
"EmployeeOnly", // name of policy
policy => policy.RequireClaim("EmployeeNumber")); // requires existence of this claim
});
}
This policy would then be used in Authorize attribute.
securing web apis
Web APIs used token-based authentication. The most common form is JSON Web Token (JWT or “jot”). Process:
- Client authenticates with auth provider.
- If successful, client is issued a token.
- Client adds token as header on requests to the API.
Auth providers can be Azure AD, OAuth, or custom implementations like IdentityServer.
JWT tokens can embed claims about a user. These can be read via tools like jwt.io.