Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Securing Web Applications and APIs with ASP.NET Core 2.2 and 3.0

Securing Web Applications and APIs with ASP.NET Core 2.2 and 3.0

Dominick Baier

January 25, 2019
Tweet

More Decks by Dominick Baier

Other Decks in Programming

Transcript

  1. Securing Web Applications and APIs
    with ASP.NET Core 2.2 and 3.0
    Dominick Baier
    @leastprivilege

    View Slide

  2. 2
    @leastprivilege / @brocklallen
    Me
    • Independent Consultant
    – Specializing on Application Security Architectures
    – Working with Software Development Teams (ISVs and in-house)
    • Co-Creator of IdentityServer & IdentityModel OSS Project
    – Certified OpenID Connect & OAuth 2.0 Implementation for .NET
    – https://identityserver.io
    • Co-Creator of PolicyServer
    – Modern Authorization Solution
    – https://policyserver.io
    email [email protected]
    blog http://leastprivilege.com
    twitter @leastprivilege
    slides https://speakerdeck.com/leastprivilege

    View Slide

  3. 3
    @leastprivilege / @brocklallen
    The dark ages…

    View Slide

  4. 4
    @leastprivilege / @brocklallen

    View Slide

  5. Modern Application Architecture
    Browser
    Native App
    Server App/Thing
    Web App
    Service Service
    Service
    Identity Provider
    Authorization Policy
    Provider

    View Slide

  6. 6
    @leastprivilege / @brocklallen
    Agenda
    • Hosting
    • Data Protection
    • Authentication
    • Authorization
    • Identity
    • IdentityServer integration
    https://github.com/leastprivilege/AspNetCoreSecuritySamples

    View Slide

  7. 7
    @leastprivilege / @brocklallen
    Hosting
    HTTPS
    HTTPS HTTP/HTTPS
    Using a
    reverse proxy
    Edge
    Kestrel
    Kestrel

    View Slide

  8. 8
    @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
    – …

    View Slide

  9. 9
    @leastprivilege / @brocklallen
    ASP.NET Core Architecture
    • Host
    • Pipeline & middleware
    • Services
    Console Application
    .NET (Core)
    ASP.NET Core
    Middleware Middleware
    User Agent MVC
    DI

    View Slide

  10. 10
    @leastprivilege / @brocklallen
    Data Protection
    • Remember this?


    validationKey="07C1493415E4405F08...6EF8B1F" />

    For giggles: "https://www.google.com/#q=

    View Slide

  11. 11
    @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

    View Slide

  12. 12
    @leastprivilege / @brocklallen

    View Slide

  13. 13
    @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

    View Slide

  14. 14
    @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

    View Slide

  15. 15
    @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();
    }

    View Slide

  16. 16
    @leastprivilege / @brocklallen
    Interacting with the authentication system
    public interface IAuthenticationService
    {
    // authenticate the specified scheme.
    Task AuthenticateAsync(HttpContext context, string scheme);
    // session management
    Task SignInAsync(HttpContext context, string scheme, ClaimsPrincipal principal,
    AuthenticationProperties properties);
    Task SignOutAsync(HttpContext context, string scheme, AuthenticationProperties properties);
    // signal that authentication is required
    Task ChallengeAsync(HttpContext context, string scheme, AuthenticationProperties properties);
    // signal that access is denied
    Task ForbidAsync(HttpContext context, string scheme, AuthenticationProperties properties);
    }

    View Slide

  17. 17
    @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 AuthenticateAsync(this HttpContext context) { }
    public static Task AuthenticateAsync(this HttpContext context, string scheme) { }
    }

    View Slide

  18. 18
    @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;
    });
    }

    View Slide

  19. 19
    @leastprivilege / @brocklallen
    Session Management (2)
    • Cookie contains
    – claims
    – metadata
    var claims = new List
    {
    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();

    View Slide

  20. 20
    @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/

    View Slide

  21. 21
    @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's
    ChallengeAsync
    method gets
    invoked
    Redirect to external
    provider
    External provider
    Authentication
    middleware asks
    handlers who wants
    to process request
    callback Handlers does the
    protocol post-
    processing
    Call sign-in handler
    (sets cookie
    containing external
    identity)
    Redirect to final URL

    View Slide

  22. 22
    @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");
    });

    View Slide

  23. 23
    @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"
    });
    }

    View Slide

  24. 24
    @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

    View Slide

  25. 25
    @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

    View Slide

  26. 26
    @leastprivilege / @brocklallen
    Programmatically using policies
    public class CustomerController : Controller
    {
    private readonly IAuthorizationService _authz;
    public CustomerController(IAuthorizationService authz)
    {
    _authz = authz;
    }
    public async Task Manage()
    {
    var result = await _authz.AuthorizeAsync(User, "ManageCustomers");
    if (result.Succeeded) return View();
    return Forbid();
    }
    }

    View Slide

  27. 27
    @leastprivilege / @brocklallen
    Custom Authorization Handler
    public class JobLevelRequirementHandler : AuthorizationHandler
    {
    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);
    }
    }
    }

    View Slide

  28. 28
    @leastprivilege / @brocklallen
    Resource-based Authorization
    Subject Object
    Operation
    - client ID
    - subject ID
    - scopes
    - more claims
    + DI
    - read
    - write
    - send via email
    - ...
    - ID
    - owner
    - more properties
    + DI

    View Slide

  29. 29
    @leastprivilege / @brocklallen
    Example: Document resource
    public class DocumentAuthorizationHandler :
    AuthorizationHandler
    {
    public override Task HandleRequirementAsync(
    AuthorizationHandlerContext context,
    OperationAuthorizationRequirement operation,
    Document resource)
    {
    // authz logic
    }
    }

    View Slide

  30. 30
    @leastprivilege / @brocklallen
    Invoking the authorization handler
    public class DocumentController : Controller
    {
    private readonly IAuthorizationService _authz;
    public DocumentController(IAuthorizationService authz)
    {
    _authz = authz;
    }
    public async Task Update(Document doc)
    {
    if ((await _authz.AuthorizeAsync(User, doc, Operations.Update)).Failure)
    {
    return Forbid();
    }
    // do stuff
    }
    }

    View Slide

  31. 31
    @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

    View Slide

  32. 32
    @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

    View Slide

  33. 33
    @leastprivilege / @brocklallen
    Thanks!
    …and (because I always forget) - we have stickers!

    View Slide