Authorization in ASP.NET Core... · Authorization in ASP.NET Core •Complete re-write •support...

of 16/16
Authorization in ASP.NET Core Brock Allen [email protected] http://brockallen.com @BrockLAllen
  • date post

    25-Apr-2020
  • Category

    Documents

  • view

    17
  • download

    0

Embed Size (px)

Transcript of Authorization in ASP.NET Core... · Authorization in ASP.NET Core •Complete re-write •support...

  • Authorization in ASP.NET Core

    Brock Allen

    [email protected]

    http://brockallen.com

    @BrockLAllen

  • Authorization in ASP.NET Core

    • Complete re-write• support for unauthorized vs forbidden

    • better separation of business code and authorization logic

    • re-usable policies

    • resource/action based authorization

    • DI enabled

  • [Authorize]

    • [Authorize] attribute still supported• [AllowAnonymous] also still

    supported

    • Custom implementations no longer supported• More on this in a bit…

    [Authorize]public class HomeController : Controller{

    [AllowAnonymous]public IActionResult Index(){

    return View();}

    [Authorize(Roles = "Sales")]public IActionResult About(){

    return View(User);}

    }

  • Unauthorized vs. Forbidden

    Unauthorized : User is anonymous

    302 to LoginPath

    Forbidden : User is authenticated

    302 to AccessDeniedPath

    public void Configure(IApplicationBuilder app){

    app.UseCookieAuthentication(new CookieAuthenticationOptions{

    AuthenticationScheme = "Cookies",AutomaticAuthenticate = true,AutomaticChallenge = true,LoginPath = new PathString("/Account/Login"),AccessDeniedPath = new PathString("/Home/Forbidden"),

    });}

  • Role-based authorization in ASP.NET

    • Roles were promoted as the primary approach to authorization• Still supported in ASP.NET Core

    • High coupling to roles is an anti-pattern

    public class CustomerController : Controller{

    [Authorize(Roles = "Sales")]public IActionResult Add(string name){

    return View();}

    }

  • Policy-based authorization

    • Framework to promote better authorization style• Decoupled from other application logic

    • Reusable from many locations in application code

    public class CustomerController : Controller{

    [Authorize(Policy = "ManageCustomers")]public IActionResult Add(string name){

    return View();}

    }

  • Defining a policy

    • List of requirements• All must pass

    • Registered in DI• Can be encapsulated

    in separate class

    public void ConfigureServices(IServiceCollection services){

    services.AddAuthorization(options =>{

    options.AddPolicy("ManageCustomers", policy =>{

    policy.RequireAuthenticatedUser().RequireRole("Sales").RequireClaim("level", "senior").RequireAssertion(ctx =>{

    return ctx.User.HasClaim("location", "USA") || ctx.User.IsInRole("Admin");

    });});

    });}

  • Programmatically using policies

    • IAuthorizationService provides access to authorization framework

    public class CustomerController : Controller{

    private readonly IAuthorizationService _authz;

    public CustomerController(IAuthorizationService authz){

    _authz = authz;}

    public async Task Add(string name){

    var allowed = await _authz.AuthorizeAsync(User, "ManageCustomers");if (!allowed) return Challenge();

    return View();}

    }

  • Razor also supports injection

    @using [email protected] IAuthorizationService _authz

    @if (await _authz.AuthorizeAsync(User, "ManageCustomers")){

    Customer List

    }

  • Custom requirements

    • Requirements can be custom and/or dynamic

    public class LocationRequirement : IAuthorizationRequirement{

    public string RequiredLocation { get; set; }}

    public async Task ViewCustomers(string country = "USA"){

    var locationRequirement = new LocationRequirement { RequiredLocation = country };var allowed = await _authz.AuthorizeAsync(User, null, locationRequirement);if (!allowed) return Challenge();

    return View();}

  • AuthorizationHandlers implement logic

    public class LocationRequirementHandler : AuthorizationHandler{

    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, LocationRequirement requirement)

    {var userLocation = context.User.FindFirst("location")?.Value;if (userLocation == requirement.RequiredLocation){

    context.Succeed(requirement);}

    return Task.FromResult(0);}

    }

    services.AddTransient();

  • Resource-based Authorization

    Subject ObjectOperation

    - client ID- subject ID- scopes

    - more claims

    + DI

    - read- write- send via email- ...

    - ID- owner

    - more properties

    + DI

  • Define resource and operations

    • Resource is just a class

    • Operations are named OperationAuthorizationRequirement

    public class Customer{

    public int Id { get; set; }public string Name { get; set; }public string SalesRepId { get; set; }

    public static OperationAuthorizationRequirement Edit= new OperationAuthorizationRequirement { Name = "Edit" };

    public static OperationAuthorizationRequirement Delete= new OperationAuthorizationRequirement { Name = "Delete" };

    }

  • Implement resource-based logic & add to DIpublic class CustomerHandler : AuthorizationHandler{

    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, OperationAuthorizationRequirement operation, Customer customer)

    {if (operation == Customer.Edit){

    var userId = context.User.FindFirst("userId").Value;if (userId == customer.SalesRepId){

    context.Succeed(operation);}

    }

    return Task.FromResult(0);}

    }

    services.AddTransient();

  • Invoke resource-based authorizationpublic class CustomerController : Controller{

    private readonly IAuthorizationService _authz;

    public CustomerController(IAuthorizationService authz){

    _authz = authz;}

    [HttpPost]public async Task Update(Customer customer){

    var allowed = await _authz.AuthorizeAsync(User, customer, Customer.Edit);if (!allowed) return Challenge();

    return View();}

    }

  • Summary

    • ASP.NET authorization framework is policy based framework

    • Policies decouple application logic from authorization logic

    • Resource based authorization is a style of policy authorization