Implementing Security in ASP.NET Core: Claims, Patterns, and
51 Slides288.01 KB
Implementing Security in ASP.NET Core: Claims, Patterns, and Policies Benjamin Day @benday www.benday.com
Benjamin Day Brookline, MA Consultant & Trainer Rental Chief Technology Officer Therapist for Teams Scrum, DevOps, Azure, Team Foundation Server, Software Architecture & Testing Microsoft MVP Pluralsight Author Scrum.org Trainer @benday @benday www.benday.com
Architecting an ASP.NET Core MVC Application for Unit Testability Just released on 12/31!
On with the show.
Overview Security Overview - Authentication vs. Authorization - Role-based security - Claims-based security Security in ASP.NET Core - [Authorize] - Role-based - Policy-based @benday www.benday.com Use the Strategy Pattern to make authorization decisions ASP.NET Core Middleware
Security Overview
Two Big Pieces Authentication @benday www.benday.com Authorization
Authentication - Who are you? Two Big Pieces Authorization - What can you do? - Permissions @benday www.benday.com
Username & passwords in your application Social logins - Google, Facebook, Twitter, Microsoft Accounts (MSA) Azure Active Directory (AAD) Authentication Windows Active Directory Lots of other options Bad news: Authentication is more complex @benday www.benday.com Good news: It’s usually external to your app
Core part of your application logic What is the user allowed to do? Authorization @benday www.benday.com User permissions - Where are permissions stored? - How do you check user permissions in your application logic?
Permissions in ASP.NET Role-based Security @benday www.benday.com Claims-based Security
Sample roles: Role-based Security - Administrators Users Power Users Sales Marketing User is a member of a role Application allows roles to do things in the application @benday www.benday.com
Beware: Role-based security has limitations
Maintenance concerns - (Not application security concerns) Fine for simple apps with simple security Role-based Security Concerns “Is User X a member of Role Y?” - Broad permissions “Is User X a member of Role Y for Item Z?” - Permissions in the context of an item - Impossible with role-based security @benday www.benday.com
Goes beyond role-based security Authorization based on a list of Claims What does the user claim to be? Claims-based Security What does the user claim to be able to do? Claims aren’t just permissions Claims can be things like - Age Name Email address Roles Claims have context @benday www.benday.com
Role-based security is just a role - Is the user a member of a role Claims are key/value pairs - Claim Type - Claim Value Claims Have Context “Is User X a member of Role Y for Item Z?” Role-based security can’t do this Claims-based security can @benday www.benday.com
ASP.NET Core security is primarily about Claims
How is security implemented in ASP.NET Core?
Security in ASP.NET Core IIdentity IPrincipal ClaimsIdentity ClaimsPrincipal @benday www.benday.com
Single Responsibility Principle Code against interfaces Things to Think About Keep logic isolated Dependency Injection Code against - IIdentity / IPrincipal - ClaimsIdentity / ClaimsPrincipal @benday www.benday.com
Assumption @benday www.benday.com You’re focused on testing Authorization
Code that checks if a user is authorized Two Types of Code Related to Authorization - Security decisions Code that you’re trying to authorize - Actions you’re trying to protect Keep these separated!!! - Single Responsibility Principle @benday www.benday.com
It’s always going to be easier to unit test the code that makes the security decisions
If you’re trying to test the decision code and the protected code at the same time
it’s probably an integration test and not a unit test
Two Ways to Implement Authorization in ASP.NET Core @benday www.benday.com Using the [Authorize] attribute - Part of ASP.NET Core - Apply to Controllers or Controller methods Custom logic - Checks against IPrincipal yourself
Apply it to a - Controller class - Controller method The [Authorize] Attribute User must be authenticated - [Authorize()] Role-based authorization - [Authorize(Roles "Administrator")] Policy-based authorization - [Authorize(Policy “AdminOnlyPolicy")] @benday www.benday.com
Nearly impossible to unit test The Bad News About the [Authorize] Attribute @benday www.benday.com It’s really hard to integration test My recommendation: - Don’t try to test that it’s working - Use reflection to check that the attribute is there with the right value(s)
Get an instance of IPrincipal Write checks against IPrincipal Checks Against IPrincipal @benday www.benday.com Succeed or fail based on the checks Recommendation: - Group the checks into methods that make the authorization decisions - Unit test the logic that makes the decisions
Encapsulates the authorization decision logic ASP.NET Core Security Policies [Authorize(Policy “AdminOnlyPolicy")] Define policies in Startup.cs Policy has two parts: - Requirement - Handler IAuthorizationRequirement AuthorizationHandler T @benday www.benday.com
IAuthorizationRequirement Configuration information related to a Policy IAuthorization Requirement Create a class Implement the interface (Optional) Provide properties for config values @benday www.benday.com
AuthorizationHandler T - T Class the implements IAuthorizationRequirement Implement HandleRequirementAsync( context, requirement) Authorization Handler T AuthorizationHandlerContext - Current authorization check info - Identity, Principal - MVC Context Make the decision - Succeed() - Fail() @benday www.benday.com
Unit test the policy handler logic in isolation Testing the Policies Focus testing on AuthorizationHandler T Integration testing policy handlers with Controllers is HARD @benday www.benday.com
Next up: Demos
Unit testing the [Authorize()] attribute Demo “Didn’t you say that was impossible?” Testing the existence of [Authorize()] using Reflection Avoids integration tests Trusts that the decision implementation works Technique is by David Pine @benday www.benday.com
David Pine Microsoft MVP Credit for This Idea Google Developer Expert Twitter: @davidpine7 https://davidpine.net/blog/ asp-net-core-security-unit-testing/ @benday www.benday.com
Multi-part demo Demo ASP.NET Core AuthorizationHandler and Policy-based Authorization Part 1: The overall code structure Part 2: Implement the unit tests Part 3: Implement AuthorizationHandler T Part 4: Create the policy - Hook it in to ASP.NET Core @benday www.benday.com
Demo The President Database is going start selling subscriptions - Basic Search - Ultimate Search Images Decide if a user is authorized to do something Strategy Pattern - Strategy encapsulates algorithms & business logic IUserAuthorizationStrategy DefaultUserAuthorizationStrategy @benday www.benday.com
ASP.NET Core Middleware
What is middleware?
It’s stuff in the middle
Middleware lets you plug your code into the ASP.NET Core execution pipeline
Middleware https://docs.microsoft.com/en-us/aspnet/core/fundamentals/middleware @benday www.benday.com
“What does middleware have to do with security?”
Not necessarily anything
but it can be really helpful in security scenarios
Use Middleware to hook into the execution pipeline and populate claims
Really easy Implementing Middleware Create a class that implements Microsoft.AspNetCore.Http.IMiddlewar e InvokeAsync(HttpContext context, RequestDelegate next) Configure Startup.cs @benday www.benday.com
Demo ASP.NET Core Middleware Load information about user’s subscription status Populate claims Unit Tests @benday www.benday.com
Any last questions?
Thank you. www.benday.com [email protected]