Top Banner
Authorization in ASP.NET Core Brock Allen [email protected] http://brockallen.com @BrockLAllen
16

Authorization in ASP.NET Core... · Authorization in ASP.NET Core •Complete re-write •support for unauthorized vs forbidden •better separation of business code and authorization

Apr 25, 2020

Download

Documents

dariahiddleston
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Authorization in ASP.NET Core... · Authorization in ASP.NET Core •Complete re-write •support for unauthorized vs forbidden •better separation of business code and authorization

Authorization in ASP.NET Core

Brock Allen

[email protected]

http://brockallen.com

@BrockLAllen

Page 2: Authorization in ASP.NET Core... · Authorization in ASP.NET Core •Complete re-write •support for unauthorized vs forbidden •better separation of business code and authorization

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

Page 3: Authorization in ASP.NET Core... · Authorization in ASP.NET Core •Complete re-write •support for unauthorized vs forbidden •better separation of business code and authorization

[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);}

}

Page 4: Authorization in ASP.NET Core... · Authorization in ASP.NET Core •Complete re-write •support for unauthorized vs forbidden •better separation of business code and authorization

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"),

});}

Page 5: Authorization in ASP.NET Core... · Authorization in ASP.NET Core •Complete re-write •support for unauthorized vs forbidden •better separation of business code and authorization

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

}

Page 6: Authorization in ASP.NET Core... · Authorization in ASP.NET Core •Complete re-write •support for unauthorized vs forbidden •better separation of business code and authorization

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

}

Page 7: Authorization in ASP.NET Core... · Authorization in ASP.NET Core •Complete re-write •support for unauthorized vs forbidden •better separation of business code and authorization

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");

});});

});}

Page 8: Authorization in ASP.NET Core... · Authorization in ASP.NET Core •Complete re-write •support for unauthorized vs forbidden •better separation of business code and authorization

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<IActionResult> Add(string name){

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

return View();}

}

Page 9: Authorization in ASP.NET Core... · Authorization in ASP.NET Core •Complete re-write •support for unauthorized vs forbidden •better separation of business code and authorization

Razor also supports injection

@using Microsoft.AspNetCore.Authorization@inject IAuthorizationService _authz

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

<div><a href="/Customers/ViewAll">Customer List</a>

</div>}

Page 10: Authorization in ASP.NET Core... · Authorization in ASP.NET Core •Complete re-write •support for unauthorized vs forbidden •better separation of business code and authorization

Custom requirements

• Requirements can be custom and/or dynamic

public class LocationRequirement : IAuthorizationRequirement{

public string RequiredLocation { get; set; }}

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

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

return View();}

Page 11: Authorization in ASP.NET Core... · Authorization in ASP.NET Core •Complete re-write •support for unauthorized vs forbidden •better separation of business code and authorization

AuthorizationHandlers implement logic

public class LocationRequirementHandler : AuthorizationHandler<LocationRequirement>{

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<IAuthorizationHandler, LocationRequirementHandler>();

Page 12: Authorization in ASP.NET Core... · Authorization in ASP.NET Core •Complete re-write •support for unauthorized vs forbidden •better separation of business code and authorization

Resource-based Authorization

Subject ObjectOperation

- client ID- subject ID- scopes

- more claims

+ DI

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

- ID- owner

- more properties

+ DI

Page 13: Authorization in ASP.NET Core... · Authorization in ASP.NET Core •Complete re-write •support for unauthorized vs forbidden •better separation of business code and authorization

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" };

}

Page 14: Authorization in ASP.NET Core... · Authorization in ASP.NET Core •Complete re-write •support for unauthorized vs forbidden •better separation of business code and authorization

Implement resource-based logic & add to DIpublic class CustomerHandler : AuthorizationHandler<OperationAuthorizationRequirement, Customer>{

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<IAuthorizationHandler, CustomerHandler>();

Page 15: Authorization in ASP.NET Core... · Authorization in ASP.NET Core •Complete re-write •support for unauthorized vs forbidden •better separation of business code and authorization

Invoke resource-based authorizationpublic class CustomerController : Controller{

private readonly IAuthorizationService _authz;

public CustomerController(IAuthorizationService authz){

_authz = authz;}

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

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

return View();}

}

Page 16: Authorization in ASP.NET Core... · Authorization in ASP.NET Core •Complete re-write •support for unauthorized vs forbidden •better separation of business code and authorization

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