implementing authorization for applications & apis · client integration strategies •provide...

28
Implementing Authorization for Applications & APIs Dominick Baier & Brock Allen https://identityserver.io [email protected] @leastprivilege / @brocklallen

Upload: others

Post on 03-Jun-2020

13 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Implementing Authorization for Applications & APIs · Client Integration Strategies •Provide a client library and call the authorization provider manually –client library takes

Implementing Authorization forApplications & APIs

Dominick Baier & Brock Allenhttps://identityserver.io

[email protected]@leastprivilege / @brocklallen

Page 2: Implementing Authorization for Applications & APIs · Client Integration Strategies •Provide a client library and call the authorization provider manually –client library takes

2@leastprivilege / @brocklallen

Authorization is hard!

• Many approaches

– roles, permissions, resource-based, ACLs… (and permutations)

– queries vs commands

• No standard solution

– often very application specific

– blurry line between authorization and business rules

– XACML good example of failed attempt to standardize

Page 3: Implementing Authorization for Applications & APIs · Client Integration Strategies •Provide a client library and call the authorization provider manually –client library takes

3@leastprivilege / @brocklallen

Modern Applications

Browser

Native App

Server App"Thing"

Web App

Web API Web API

Web API

Identity Provider

Page 4: Implementing Authorization for Applications & APIs · Client Integration Strategies •Provide a client library and call the authorization provider manually –client library takes

4@leastprivilege / @brocklallen

Identity != Permissions

Page 5: Implementing Authorization for Applications & APIs · Client Integration Strategies •Provide a client library and call the authorization provider manually –client library takes

5@leastprivilege / @brocklallen

Overloaded Security Token

{"iss": "https://idsrv4","exp": 1340819380,"aud": [ "api1", "api2"],"amr": [ "password" ],"auth_time": 12340819300

"sub": "182jmm199","name": "Doug Ross",

"role": ["Approver","Doctor"

],

"permission": ["DeleteData","ManageCustomers","ChangeTreatmentPlan"

] }

authenticationmetadata

identity

authorizationdata

roles

Page 6: Implementing Authorization for Applications & APIs · Client Integration Strategies •Provide a client library and call the authorization provider manually –client library takes

6@leastprivilege / @brocklallen

Token Usage

Patient Data API

Oncology API

Cardiac API

Page 7: Implementing Authorization for Applications & APIs · Client Integration Strategies •Provide a client library and call the authorization provider manually –client library takes

7@leastprivilege / @brocklallen

Permissions and Tokens

• Separation of concerns

– authentication vs authorization

– identity system does not have intimate knowledge of application specific authorization rules

• "do authorization as close as possible to the resource you are trying to protect"

• Tokens can be re-used at several places

– claims might have different meaning for each consumer

– token & claim bloat

• Permissions might change

– only way to update the data would be to get a new token

Page 8: Implementing Authorization for Applications & APIs · Client Integration Strategies •Provide a client library and call the authorization provider manually –client library takes

8@leastprivilege / @brocklallen

Identity + Permissions== Authorization

Page 9: Implementing Authorization for Applications & APIs · Client Integration Strategies •Provide a client library and call the authorization provider manually –client library takes

9@leastprivilege / @brocklallen

Modern Applications

Browser

Native App

Server App"Thing"

Web App

Web API Web API

Web API

Identity ProviderAuthorization Provider

Page 10: Implementing Authorization for Applications & APIs · Client Integration Strategies •Provide a client library and call the authorization provider manually –client library takes

10@leastprivilege / @brocklallen

Patient API Oncology API Cardiac API

Identity Provider Authorization Provider

authentication +token request

get client specificpermissions

call APIs

get API specificpermissions

Admin UI

Page 11: Implementing Authorization for Applications & APIs · Client Integration Strategies •Provide a client library and call the authorization provider manually –client library takes

11@leastprivilege / @brocklallen

Global roles(static / dynamic)Management

API

ClientAPI

App specific roles(static / dynamic)

Roles to permissionmappings

resources & rules(future)

Applications

Admin UI

ClientLibrary

Our Vision

{"sub": "jd9j91199j1","role": "Doctor","contractor": "true"

}

Authorization Provider

Page 12: Implementing Authorization for Applications & APIs · Client Integration Strategies •Provide a client library and call the authorization provider manually –client library takes

12@leastprivilege / @brocklallen

Client Integration Strategies

• Provide a client library and call the authorization provider manually

– client library takes care of caching & refreshing

• Augment the ClaimsPrincipal

– e.g. using claims transformation in pipeline

• Use a specialized authorization API

– e.g. ASP.NET Core Authorization

Page 13: Implementing Authorization for Applications & APIs · Client Integration Strategies •Provide a client library and call the authorization provider manually –client library takes

13@leastprivilege / @brocklallen

Client Library

public class TreatmentController : Controller{

private readonly AuthorizationProviderClient _client;

public TreatmentController(AuthorizationProviderClient client){

_client = client;}

public async Task<IActionResult> Update(TreatmentUpdateModel model){

var (roles, permissions) = await _client.GetAuthorizationAsync(User);

// orvar allowed = await _client.IsInRoleAsync(User, "Doctor");

// orallowed = await _client.HasPermissionAsync(User, "PrescribeMedication");

}}

Page 14: Implementing Authorization for Applications & APIs · Client Integration Strategies •Provide a client library and call the authorization provider manually –client library takes

14@leastprivilege / @brocklallen

Augment the ClaimsPrincipal

• Inject roles and permissions into current principal

– backwards compat with existing libraries

[Authorize(Roles = "Doctor")]public async Task<IActionResult> Update(TreatmentUpdateModel model){

...}

Page 15: Implementing Authorization for Applications & APIs · Client Integration Strategies •Provide a client library and call the authorization provider manually –client library takes

15@leastprivilege / @brocklallen

ASP.NET Core Authorization

• Very flexible authorization library

– created for ASP.NET Core, but has been back-ported by the community*

• Introduces a policy-based framework

– decoupling authorization logic from business code

– extensible

– supports resource-based authorization

* https://github.com/DavidParks8/Owin-Authorization

Page 16: Implementing Authorization for Applications & APIs · Client Integration Strategies •Provide a client library and call the authorization provider manually –client library takes

16@leastprivilege / @brocklallen

Authorization Policies

services.AddAuthorization(options =>{

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

policy.RequireAuthenticatedUser();policy.RequireClaim("permission", "PrescribeMedication");

});};

[Authorize("PrescribeMedication")]public IActionResult Update(){

// stuff}

Startup

Controller

Page 17: Implementing Authorization for Applications & APIs · Client Integration Strategies •Provide a client library and call the authorization provider manually –client library takes

17@leastprivilege / @brocklallen

Programmatically using policiespublic class TreatmentController : Controller{

private readonly IAuthorizationService _authz;

public TreatmentController(IAuthorizationService authz){

_authz = authz;}

public async Task<IActionResult> Update(){

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

return View();}

}

Page 18: Implementing Authorization for Applications & APIs · Client Integration Strategies •Provide a client library and call the authorization provider manually –client library takes

18@leastprivilege / @brocklallen

…or from a View

@using Microsoft.AspNetCore.Authorization@inject IAuthorizationService _authz

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

<div><a href="/treatment/update">Update</a>

</div>}

Page 19: Implementing Authorization for Applications & APIs · Client Integration Strategies •Provide a client library and call the authorization provider manually –client library takes

19@leastprivilege / @brocklallen

Policy Provider

• Extensibility point that allows creating policies on the fly

– no need to create explicit "permission policies" anymore

// this policy is not statically defined// but gets created dynamically// check for permission claim[Authorize("PrescribeMedication")]public IActionResult Update(){

// stuff}

Controller

Page 20: Implementing Authorization for Applications & APIs · Client Integration Strategies •Provide a client library and call the authorization provider manually –client library takes

20@leastprivilege / @brocklallen

Example Policy Provider

public class AuthorizationPolicyProvider : DefaultAuthorizationPolicyProvider{

public async override Task<AuthorizationPolicy> GetPolicyAsync(string policyName){

// check static policies firstvar policy = await base.GetPolicyAsync(policyName);if (policy != null) return policy;

if (await _client.HasPermissionAsync(_contextAccessor.HttpContext.User, policyName)){

return Allowed;}

return Denied;}

}

Page 21: Implementing Authorization for Applications & APIs · Client Integration Strategies •Provide a client library and call the authorization provider manually –client library takes

21@leastprivilege / @brocklallen

Custom Requirements

public class MedicationRequirement : IAuthorizationRequirement{

public string MedicationName { get; set; }public int Amount { get; set; }

}

Page 22: Implementing Authorization for Applications & APIs · Client Integration Strategies •Provide a client library and call the authorization provider manually –client library takes

22@leastprivilege / @brocklallen

Requirement Handlerpublic class MedicationRequirementHandler : AuthorizationHandler<MedicationRequirement>{

private readonly AuthorizationProviderClient _client;

public MedicationRequirementHandler(AuthorizationProviderClient client) {_client = client;

}

protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, MedicationRequirement requirement)

{var user = context.User; var allowed = false;

if (await _client.HasPermissionAsync(user, "PrescribeMedication")){

if (requirement.Amount < 10) allowed = true;else allowed = await _client.IsInRoleAsync(user, "Doctor");

if (allowed || requirement.MedicationName == "placebo"){

context.Succeed(requirement);}

}}

}

Page 23: Implementing Authorization for Applications & APIs · Client Integration Strategies •Provide a client library and call the authorization provider manually –client library takes

23@leastprivilege / @brocklallen

Using a custom Requirement

public async Task<IActionResult> Prescribe(int amount){

var meds = new MedicationRequirement{

MedicationName = "aspirin", Amount = amount

};

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

return View("Confirm");}

Page 24: Implementing Authorization for Applications & APIs · Client Integration Strategies •Provide a client library and call the authorization provider manually –client library takes

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

Page 25: Implementing Authorization for Applications & APIs · Client Integration Strategies •Provide a client library and call the authorization provider manually –client library takes

25@leastprivilege / @brocklallen

Example: Patient Resource

public class Patient{

public ICollection<string> Allergies { get; set; } }

Page 26: Implementing Authorization for Applications & APIs · Client Integration Strategies •Provide a client library and call the authorization provider manually –client library takes

26@leastprivilege / @brocklallen

Patient Handlerpublic class PatientHandler : AuthorizationHandler<PrescribeMedicationOperation, Patient>{

private readonly AuthorizationProviderClient _client;

public PatientHandler(AuthorizationProviderClient client){

_client = client;}

protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, PrescribeMedicationOperation medication, Patient patient)

{// medication requirement logic

if (!patient.Allergies.Contains(medication.MedicationName)){

allowed = false;}

if (allowed) context.Succeed(medication);}

}

Page 27: Implementing Authorization for Applications & APIs · Client Integration Strategies •Provide a client library and call the authorization provider manually –client library takes

27@leastprivilege / @brocklallen

Invoking the Patient Handler

public async Task<IActionResult> PrescribeMed(int amount, string medication){

var operation = new PrescribeMedicationOperation{

Amount = amount, MedicationName = medication

};

var patient = new Patient { Allergies = { "aspirin" } };

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

return View("Confirmation");}

Page 28: Implementing Authorization for Applications & APIs · Client Integration Strategies •Provide a client library and call the authorization provider manually –client library takes

28@leastprivilege / @brocklallen

Conclusion

• Different levels of authorization lend to different abstractions

Application/API

application access

feature

feature

feature access

application logic?