securing web applications and apis with asp.net core 2.2 and 3 · modern application architecture...
Post on 20-May-2020
8 Views
Preview:
TRANSCRIPT
Securing Web Applications and APIs with ASP.NET Core 2.2 and 3.0
Brock Allen
brockallen@gmail.com
http://brockallen.com
@BrockLAllen
2@leastprivilege / @brocklallen
The dark ages…
Modern Application Architecture
Browser
Native App
Server App/Thing
Web App
Service Service
Service
Identity ProviderAuthorization Policy Provider
4@leastprivilege / @brocklallen
Agenda
• Hosting
• Data Protection
• Authentication
• Authorization
• Identity
• IdentityServer integration
https://github.com/leastprivilege/AspNetCoreSecuritySamples
5@leastprivilege / @brocklallen
Hosting
HTTPS
HTTPS HTTP/HTTPSUsing a reverse proxy
Edge
Kestrel
Kestrel
6@leastprivilege / @brocklallen
Kestrel Security
• HTTPS by default– static configuration or dynamic selection (SNI)– dotnet dev-certs tool for local development
• Need to fine-tune transport parameters when doing edge hosting– Keep-Alive timeouts– Request Header limits– Request/Response buffer sizes– Request line size– Request header limits– Request header count limits– Request/Response body timeouts & data rates– Total client connections– Handshake timeous– …
7@leastprivilege / @brocklallen
ASP.NET Core Architecture
• Host
• Pipeline & middleware
• Services
Console Application
.NET (Core)
ASP.NET Core
Middleware MiddlewareUser Agent MVC
DI
8@leastprivilege / @brocklallen
Data Protection
• Remember this?
<system.web><!– copied from the 90ies --><machineKey decryptionKey="656E7...617365206865726547A5"
validationKey="07C1493415E4405F08...6EF8B1F" /> </system.web>
For giggles: "https://www.google.com/#q=<machineKey filetype:config"
9@leastprivilege / @brocklallen
Data Protection in ASP.NET Core
• Keys are stored outside of application directory– profile
– registry
– Azure web apps magic
– Redis
– manual
• Automatic key management– 512 bit master key / AES-256 CBC / HMACSHA256
– rotated every 90 days
– automatic application isolation
• Key protection– DPAPI, X509, Azure KeyVault
10@leastprivilege / @brocklallen
11@leastprivilege / @brocklallen
Who uses Data Protection?
• ASP.NET Core
– protecting cookies
– anti-forgery
– protecting OpenID Connect/OAuth state
– [TempData]
• You
– IDataProtectionProvider service
– can be also used with non-ephemeral data
• if key ring is properly stored / backed-up
12@leastprivilege / @brocklallen
Authentication in ASP.NET Core
• Authenticating users/clients
– local
– Google, Facebook, and other proprietary providers*
– OpenID Connect, WS-Federation & SAML** for standards-based external authentication
– JSON web token (JWT) for token-based API authentication
• Session Management
– cookies
* 40+ more https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers ** https://github.com/Sustainsys/Saml2
13@leastprivilege / @brocklallen
Setting up authentication
public void ConfigureServices(IServiceCollection services){
services.AddAuthentication(defaultScheme: "cookies").AddCookies(scheme: "cookies").AddGoogle(scheme: "google").AddOpenIdConnect(scheme: "idsrv");
}
public void Configure(IApplicationBuilder app){
app.UseAuthentication();}
14@leastprivilege / @brocklallen
Interacting with the authentication system
public interface IAuthenticationService{
// authenticate the specified scheme.Task<AuthenticateResult> AuthenticateAsync(HttpContext context, string scheme);
// session managementTask SignInAsync(HttpContext context, string scheme, ClaimsPrincipal principal,
AuthenticationProperties properties);Task SignOutAsync(HttpContext context, string scheme, AuthenticationProperties properties);
// signal that authentication is requiredTask ChallengeAsync(HttpContext context, string scheme, AuthenticationProperties properties);
// signal that access is deniedTask ForbidAsync(HttpContext context, string scheme, AuthenticationProperties properties);
}
15@leastprivilege / @brocklallen
Interacting with the authentication system (2)
• Convenience extension methods
public static class AuthenticationHttpContextExtensions{
public static Task SignInAsync(this HttpContext context, ClaimsPrincipal principal) { }public static Task SignInAsync(this HttpContext context, string scheme, ClaimsPrincipal principal) { }
public static Task SignOutAsync(this HttpContext context) { }public static Task SignOutAsync(this HttpContext context, string scheme) { }
public static Task ChallengeAsync(this HttpContext context) { }public static Task ChallengeAsync(this HttpContext context, string scheme) { }
public static Task ForbidAsync(this HttpContext context) { }public static Task ForbidAsync(this HttpContext context, string scheme) { }
public static Task<AuthenticateResult> AuthenticateAsync(this HttpContext context) { }public static Task<AuthenticateResult> AuthenticateAsync(this HttpContext context, string scheme) { }
}
16@leastprivilege / @brocklallen
Session Management (1)
public void ConfigureServices(IServiceCollection services){
services.AddAuthentication(defaultScheme: "Cookies").AddCookie("Cookies", options =>{
options.LoginPath = "/account/login";options.AccessDeniedPath = "/account/denied";
options.Cookie.Name = "myapp";options.Cookie.Expiration = TimeSpan.FromHours(8);options.SlidingExpiration = false;
options.Cookie.SameSite = SameSiteMode.Lax;});
}
17@leastprivilege / @brocklallen
Session Management (2)
• Cookie contains
– claims
– metadata
var claims = new List<Claim>{
new Claim("sub", "123"),new Claim("name", "Bob")
};
var ci = new ClaimsIdentity(claims, "password", "name", "role");
var props = new AuthenticationProperties{
Items ={
{ "token", "abc" }}
};
await HttpContext.SignInAsync(new ClaimsPrincipal(ci), props);
await HttpContext.SignOutAsync();
18@leastprivilege / @brocklallen
Advanced Features
• The cookie handler has an eventing model
– additional validation on incoming cookie
– redirect/sign-in/sign-out interception
– sign-out cleanup
• Session storage mechanism can be replaced
– e.g. server-side (Redis, Cosmos DB..)
– keeps cookies small
– allows for server-side revocation
https://leastprivilege.com/2019/01/14/automatic-oauth-2-0-token-management-in-asp-net-core/
19@leastprivilege / @brocklallen
External Authentication
• Special type of authentication handler – RemoteAuthenticationHandler
– ChallengeAsync sends authentication/token request
– SignOutAsync sends sign-out request
– provides callback endpoints to process protocol responses
Challenge(scheme)
Handler'sChallengeAsync
method getsinvoked
Redirect to externalprovider
External provider
Authentication middleware asks
handlers who wantsto process request
callback Handlers does theprotocol post-
processing
Call sign-in handler(sets cookie
containing externalidentity)
Redirect to final URL
20@leastprivilege / @brocklallen
Example: Sign-in & Token Request w/ OpenID Connect
services.AddAuthentication(options =>{
options.DefaultScheme = "cookies";options.DefaultChallengeScheme = "oidc";
}).AddCookie("cookies").AddOpenIdConnect("oidc", options =>{
options.Authority = "https://demo.identityserver.io";options.ClientId = "server.hybrid";options.ClientSecret = "secret";
options.ResponseType = "code id_token";
options.Scope.Clear();options.Scope.Add("openid");options.Scope.Add("api");
});
21@leastprivilege / @brocklallen
API Authentication
• Built-in support for JWT bearer tokens
– see https://github.com/IdentityModel/IdentityModel.AspNetCore.OAuth2Introspection
for RFC 7662 support
public void ConfigureServices(IServiceCollection services){
services.AddAuthentication("jwt").AddJwtBearer("jwt", options =>{
options.Authority = "https://demo.identityserver.com";options.Audience = "api"
});}
22@leastprivilege / @brocklallen
Authorization
• Policy-based authorization– based on properties of the caller/user
• Resource-based authorization– takes the resource that is being manipulated into account as well
• Authorization is a service– DI based
– extensible
– testable
• Will be also available as middleware in 3.0
https://github.com/blowdart/AspNetAuthorizationWorkshop
23@leastprivilege / @brocklallen
Example Authorization Policy
services.AddAuthorization(options =>{
options.AddPolicy("ManageCustomers", policy =>{
policy.RequireAuthenticatedUser();policy.RequireClaim("department", "sales");policy.RequireClaim("status", "senior");
});});
[Authorize("ManageCustomers")]public IActionResult Manage(){
// stuff}
Startup
Controller
24@leastprivilege / @brocklallen
Programmatically using policiespublic class CustomerController : Controller{
private readonly IAuthorizationService _authz;
public CustomerController(IAuthorizationService authz){
_authz = authz;}
public async Task<IActionResult> Manage(){
var result = await _authz.AuthorizeAsync(User, "ManageCustomers");if (result.Succeeded) return View();
return Forbid();}
}
25@leastprivilege / @brocklallen
Custom Authorization Handlerpublic class JobLevelRequirementHandler : AuthorizationHandler<JobLevelRequirement>{
private readonly IOrganizationService _service;
public JobLevelRequirementHandler(IOrganizationService service){
_service = service;}
protected override void Handle(AuthorizationContext context, JobLevelRequirement requirement)
{var currentLevel = _service.GetJobLevel(context.User);
if (currentLevel == requirement.Level){
context.Succeed(requirement);}
}}
26@leastprivilege / @brocklallen
Resource-based Authorization
Subject ObjectOperation
- client ID- subject ID- scopes
- more claims
+ DI
- read- write- send via email- ...
- ID- owner
- more properties
+ DI
27@leastprivilege / @brocklallen
Example: Document resource
public class DocumentAuthorizationHandler :AuthorizationHandler<OperationAuthorizationRequirement, Document>
{public override Task HandleRequirementAsync(
AuthorizationHandlerContext context,OperationAuthorizationRequirement operation,Document resource)
{// authz logic
}}
28@leastprivilege / @brocklallen
Invoking the authorization handlerpublic class DocumentController : Controller{
private readonly IAuthorizationService _authz;
public DocumentController(IAuthorizationService authz){
_authz = authz;}
public async Task<IActionResult> Update(Document doc){
if ((await _authz.AuthorizeAsync(User, doc, Operations.Update)).Failure){
return Forbid();}
// do stuff}
}
29@leastprivilege / @brocklallen
ASP.NET Identity
• Library for managing identity data for users
– manages credentials (e.g. passwords, complexity)
– lockout for brute force prevention
– mapping external authentication
• Stores this data in database
– can be used to maintain additional user attributes/claims
• Provides primitives for email confirmation, password reset, and MFA workflows
• Abstraction on cookie authentication handler
– sign-in/sign-out
30@leastprivilege / @brocklallen
The missing link
• ASP.NET Identity templates are geared towards local authentication
• IdentityServer adds OpenID Connect & OAuth 2.0 for remote authentication
• ASP.NET Core 2.2 + ships with an IdentityServer integration library
– "zero config" IdentityServer using ASP.NET Identity & local APIs
– Web API and SPA template
• Will be expanded to more advanced scenarios in 3.0
– separating IdentityServer from APIs
– dynamic client registration
31@leastprivilege / @brocklallen
Thanks!…and (because I always forget) - we have stickers!
top related