Securing Web Applicasons and APIs with .NET & ASP.NET today

Securing Web Applica0ons and APIs with .NET & ASP.NET today and tomorrow Dominick Baier hCp://leastprivilege.com @leastprivilege Dominick Baier •  Independent Consultant –  Specializing on Iden9ty & Access Control –  Working with SoAware Development Teams (ISVs and in-­‐house) •  Creator and Maintainer of Iden0tyServer OSS Project –  OpenID Connect & OAuth 2.0 Implementa9on on OWIN –  hLp://iden9tyserver.io • 
• 
• 
• 
MicrosoM MVP for Developer Security .NET Founda0on Advisory Board [email protected] hCp://leastprivilege.com @leastprivilege 2 Where are we? ASP.NET =< 4.5 ASP.NET 4.5 ASP.NET 5 System.Web.dll Modules & Handlers ASP.NET WebForms ASP.NET MVC ASP.NET Web API ASP.NET SignalR (Simple) Membership @leastprivilege 3 @leastprivilege 4 "Empty Web Applica9on" @leastprivilege 5 Mo9va9on •  System.Web.dll (aka ASP.NET) –  12+ year old web framework –  Unnamed MicrosoA employee on System.Web: •  “We fix one bug and open seven new ones” –  Always executes lots of WebForms-­‐specific code hCps://twiCer.com/aeinbu/status/407816285058514944 @leastprivilege 6 Where are we? ASP.NET =< 4.5 ASP.NET 4.5 "System.Web.dll" Modules & Handlers ASP.NET WebForms ASP.NET MVC (Simple) Membership "System.Web.dll" Modules & Handlers ASP.NET WebForms ASP.NET MVC OWIN & Katana ASP.NET Web API ASP.NET SignalR ASP.NET Iden9ty 1/2 @leastprivilege ASP.NET 5 7 What is OWIN? @leastprivilege 8 OWIN Specifica9on •  Environment models HTTP request/response –  IDic%onary<string, object> •  All .NET primi9ves so no framework dependencies –  Standard set of key/value pairs @leastprivilege Key Type owin.RequestScheme string owin.RequestMethod string owin.RequestPath string owin.RequestBody Stream owin.RequestHeaders IDic9onary<string, string[]> owin.ResponseStatusCode int owin.ResponseHeaders IDic9onary<string, string[]> owin.ResponseBody Stream 9 Middleware using MidFunc = Func<AppFunc, AppFunc>; Func<IDictionary<string, object>>, Task> Middleware using AppFunc = Func<IDictionary<string, object>>, Task> @leastprivilege 10 Middleware Architecture •  Middleware are linked components that process requests •  Applica0on code targe0ng a framework (e.g. Web API) Host OWIN Server User Agent @leastprivilege Some Middleware Some Other Middleware Applica9on 11 Katana == MicrosoA.Owin.* @leastprivilege 12 Where are we? ASP.NET =< 4.5 ASP.NET 4.5 ASP.NET 5 "System.Web.dll" Modules & Handlers ASP.NET WebForms ASP.NET MVC (Simple) Membership "System.Web.dll" Modules & Handlers ASP.NET WebForms ASP.NET MVC OWIN & Katana ASP.NET Web API ASP.NET SignalR ASP.NET Iden9ty 1/2 "Desktop" CLR & Core CLR MVC 6 SignalR 3 ASP.NET Iden9ty 3 @leastprivilege 13 ASP.NET 5 Architecture •  ASP.NET 5 is the run0me –  can host OWIN and "na9ve" middleware •  MVC 6 is MicrosoM's applica0on framework –  is OWIN compa9ble Host OWIN Server User Agent @leastprivilege OWIN Middleware ASP.NET 5 Middleware MVC 6 14 Security in the new Architecture •  Everything is based on claims •  Authen0ca0on is implemented as middleware –  cookies –  external authen9ca9on •  social providers (Google, Facebook etc…) •  integra9on providers (WS-­‐Federa9on) •  modern applica9ons (OpenID Connect) •  Other security related middleware –  CORS –  Audi9ng @leastprivilege 15 Authen9ca9on Manager •  Katana introduces uniform authen0ca0on API public interface IAuthenticationManager { ClaimsPrincipal User { get; set; } void SignIn(params ClaimsIdentity[] identities); void SignOut(params string[] authenticationTypes); Task<AuthenticateResult> AuthenticateAsync(string authenticationType); void Challenge(params string[] authenticationTypes); IEnumerable<AuthenticationDescription> GetAuthenticationTypes(); } @leastprivilege 16 Cookie Middleware •  Forms Authen0ca0on replacement public void Configuration(IAppBuilder app) { var options = new CookieAuthenticationOptions { AuthenticationType = "Cookies", LoginPath = new PathString("/account/login"), ExpireTimeSpan = TimeSpan.FromHours(4), CookieSecure = CookieSecureOption.Always }; app.UseCookieAuthentication(options); } @leastprivilege 17 External Authen9ca9on Name Descrip0on Google OAuth2 TwiLer OAuth1 Facebook OAuth2 MicrosoA Account OAuth2 JWT Bearer (JSON web token) (Azure) Ac9ve Directory Bearer (JSON web tokens) Federa9on WS-­‐Federa9on OIDC OpenID Connect Yahook, LinkedIn, Steam, GitHub, Instagram, StackExchange, BaLle.Net, Asana, HealthGraph, SalesForce (hLps://github.com/owin-­‐middleware/OwinOAuthProviders) hLp://www.oauthforaspnet.com/ @leastprivilege 18 The big Picture Security Token Service Google, Facebook etc… Enterprise Authen0ca0on Federa0on Registra0on / Account linking 1 Browser Web App 2 @leastprivilege WS-­‐Federa0on OpenID Connect + Cookies 19 OpenID Connect Provider Middleware @leastprivilege 20 Authen9ca9on/Access Tokens in Nutshell GET /authorize ?client_id=app1 &redirect_uri=hCps://<callback> &response_type=id_token token &scope=openid email api1 api2 @leastprivilege 21 Authen9ca9on @leastprivilege 22 Consent @leastprivilege 23 Response GET or POST /callback id_token=xyz…123 token=udh…988 @leastprivilege 24 Token-­‐based Authen9ca9on Security Token Service (1) (2) Token Middleware @leastprivilege API 25 Target Architecture Security Token Service Browser Web App Web API Na0ve App Web API Web API Server App @leastprivilege 26 Security Protocols Browser Security Token Service OpenID Connect Web App OAuth2 Web API OAuth2 Na0ve App OAuth2 Web API OAuth2 Web API OAuth2 Server App OAuth2 @leastprivilege 27 ASP.NET 5 @leastprivilege 28 ClaimsPrincipal & the new Authen9ca9on APIs •  Users are now ClaimsPrincipals –  H6pContext.User, Controller.User •  H.pResponse.SignIn/SignOut –  Sign in/out a user •  HCpResponse.Challenge –  Ini9ate challenge (also new ChallengeResult) •  H.pContext.Authen=cate –  Authen9cate using a specific scheme •  H.pContext.GetAuthen=ca=onSchemes –  Get available authen9ca9on schemes @leastprivilege 29 Authen9ca9on Middleware •  Authen0ca0on implemented as middleware •  By ASP.NET Team –  Cookies –  Google, MicrosoA Account, TwiLer, Facebook –  OAuth2 Bearer Tokens •  By Azure AD Team –  OpenID Connect –  WS-­‐Federa9on @leastprivilege 30 Cookie Authen9ca9on Startup app.UseCookieAuthentication(options => { options.LoginPath = new PathString("/account/login"); options.AutomaticAuthentication = true; options.AuthenticationScheme = "Cookies"; }); Account controller if (IsValid(username, password)) { var principal = CreatePrincipal(username); Response.SignIn("Cookies", principal); } @leastprivilege 31 Data Protec9on •  Cookies (amongst other things) need protec0on –  <machineKey /> in previous versions •  New DataProtec0on API is much more powerful and flexible –  No more secrets in configura9on file –  Automa9c key roll over and protec9on –  But needs some planning ahead •  hCp://docs.asp.net/en/latest/security/data-­‐
protec0on/index.html @leastprivilege 32 Default Key Container Loca9ons •  On Azure Web Apps (no encryp0on) –  %HOME%\ASP.NET\DataProtec9on-­‐Keys •  If user profile is loaded (encrypted) –  %LOCALAPPDATA%\ASP.NET\DataProtec9on-­‐Keys •  IIS / no profile (encrypted) –  Registry HKLM •  In-­‐Memory •  Manual configura0on @leastprivilege <?xml version="1.0" encoding="uw-­‐8"?> <key id="eacc6495-­‐83a3-­‐4aaf-­‐ad29-­‐fee164c69963" version="1"> <crea9onDate>2015-­‐05-­‐02T08:20:38.6577127Z</crea9onDate> <ac9va9onDate>2015-­‐05-­‐02T08:20:38.6424674Z</ac9va9onDate> <expira9onDate>2015-­‐07-­‐31T08:20:38.6424674Z</expira9onDate> <descriptor> <descriptor> <encryp9on algorithm="AES_256_CBC" /> <valida9on algorithm="HMACSHA256" /> <encryptedSecret> <encryptedKey xmlns=""> <!-­‐-­‐ This key is encrypted with Windows DPAPI. -­‐-­‐> <value>AQ...g==</value> </encryptedKey> </encryptedSecret> </descriptor> </descriptor> </key> 33 External Authen9ca9on •  Invoke with H.pResponse.Challenge or ChallengeResult app.UseCookieAuthentication(options => { options.LoginPath = new PathString("/account/login"); options.AutomaticAuthentication = true; options.AuthenticationScheme = "Cookies"; }); app.UseGoogleAuthentication(options => { options.ClientId = "434…48"; options.ClientSecret = "3gc…6PWo"; options.AuthenticationScheme = "Google"; options.SignInScheme = "Cookies"; }); @leastprivilege 34 OAuth2 Bearer Tokens •  Expects JSON Web Token (JWT) •  Supports OpenID Connect Discovery Document app.UseOAuthBearerAuthentication(options => { options.Authority = "https://identityserver.io"; options.Audience = "https://identityserver.io/resources"; options.AutomaticAuthentication = true; }); @leastprivilege 35 Authoriza9on •  Complete re-­‐write –  Separa9on of controller/business code and authoriza9on policy –  Re-­‐usable policies –  DI enabled –  Claims-­‐aware •  S0ll in flux @leastprivilege 36 [Authorize] •  General concept stays the same @leastprivilege [Authorize] public class HomeController : Controller { [AllowAnonymous] public IActionResult Index() { return View(); } [Authorize(Roles = "Sales")] public IActionResult About() { return View(User); } } 37 Authoriza9on policies Startup services.ConfigureAuthorization(options => { options.AddPolicy("BlueTeamIntern", policy => { policy.RequireAuthenticatedUser(); policy.RequireClaim("team", "blue"); policy.RequireClaim("status", "intern"); }); Controller }; [Authorize("BlueTeamIntern")] public IActionResult Blue() { // stuff } @leastprivilege 38 Custom Requirements public class TeamRequirement : AuthorizationHandler<TeamRequirement>, IAuthorizationRequirement { private readonly string _status; private readonly string _team; public TeamRequirement(string team, string status) { _team = team; _status = status; } public override void Handle( AuthorizationContext context, TeamRequirement requirement) { if (context.User.HasClaim("team", _team) && context.User.HasClaim("status", _status)) { context.Succeed(requirement); } } } @leastprivilege 39 Resource-­‐based Authoriza9on public class GameAuthorizationHandler : AuthorizationHandler<OperationAuthorizationRequirement, Game> { private readonly IPermissionStore _permissions; public GameAuthorizationHandler(IPermissionStore permissions) { _permissions = permissions; } public override void Handle( AuthorizationContext context, OperationAuthorizationRequirement requirement, Game resource) { // custom logic } } @leastprivilege 40 Registering the authoriza9on handler •  In RegisterServices services.AddScoped<IPermissionStore, PermissionStore>(); services.AddTransient<IAuthorizationHandler, GameAuthorizationHandler>(); @leastprivilege 41 Invoking the authoriza9on handler public class GameController : Controller { private readonly IAuthorizationService _authz; public GameController(IAuthorizationService authz) { _authz = authz; } public IActionResult Start() { var game = new Game { Location = "DataCenterEast", Type = "Virus" }; if (_authz.Authorize(User, game, GameOperations.Attack)) { return Content("Attack has started..."); } return HttpUnauthorized(); } } @leastprivilege 42 Thank you! @leastprivilege 43