Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Securing (ASP.NET) Web API Architectures

Securing (ASP.NET) Web API Architectures

Dominick Baier

March 03, 2013
Tweet

More Decks by Dominick Baier

Other Decks in Programming

Transcript

  1. Securing  (ASP.NET)  Web  API   based  Architectures   Dominick  Baier

      h?p://leastprivilege.com   @leastprivilege   think mobile!
  2. 2   @leastprivilege   Dominick  Baier   •  Security  consultant

     at  thinktecture   •  Focus  on   –  security  in  distributed  applica9ons   –  iden9ty  management   –  access  control   –  Windows/.NET  security   –  cloud  compu9ng     •  MicrosoI  MVP  for  Developer  Security   •  [email protected]   •  h?p://leastprivilege.com   think mobile!
  3. 3   @leastprivilege   Agenda   •  HTTP  Security  

    •  ASP.NET  Web  API  Security  Overview   •  AuthenOcaOon   •  AuthorizaOon   •  OAuth2   •  Scenarios    
  4. 6   @leastprivilege   Security  model  for  HTTP-­‐based   services

      •  Simple  model   –  HTTP  +  content  +  SSL   •  Whenever  authenOcaOon  is  required   –  Status  code  of  401  indicates  unauthorized   –  WWW-­‐Authen0cate  response  header  indicates  preferred   authen9ca9on  method   WWW-­‐AuthenOcate:  Scheme  realm="myapp"   Status  Code:  401  unauthorized  
  5. 7   @leastprivilege   Authen9ca9on  for  HTTP-­‐based   services  

    •  CredenOals  transmi?ed  (typically)  via  Authoriza.on   header   •  e.g.  Basic  authen9ca9on,  OAuth  access  tokens   •  some9mes  other  means  (query  string,  cookie…)   AuthorizaOon:  scheme  credenOal   GET  /service/resource  
  6. 8   @leastprivilege   Authoriza9on  filter   •  Determines  if

     a  resource  needs  authenOcaOon   –  and  if  yes,  which  claims  are  required   –  [AllowAnonymous]  to  skip  authoriza9on  for  an  ac9on   –  emits  the  401  status  code,  if  unsuccessful   //  minimum  requirement  is  successful  authentication   [Authorize]   public  DataController  :  ApiController   {          [AllowAnonymous]          public  Data  Get()            {  …  }            [Authorize(Role  =  "Foo")]          public  HttpResponseMessage  Delete(int  id)          {  …  }   }  
  7. 9   @leastprivilege   Custom  authoriza9on  filter   •  Derive

     from  AuthorizeA1ribute   –  decorate  controller  and  ac9ons   public  class  PremiumUsersOnlyAttribute  :  AuthorizeAttribute   {          protected  override  bool  IsAuthorized(HttpActionContext  context)          {                  ClaimsPrincipal  client  =  ClaimsPrincipal.Current;                    //  custom  authorization  logic          }              protected  override  void  HandleUnauthorizedRequest(              HttpActionContext  actionContext)          {                  //  custom  response          }   }  
  8. 10   @leastprivilege   Applica9on/Client  types   •  Same-­‐Domain  

    –  Web  APIs  and  clients  live  in  the  same  domain   •  typically  server-­‐rendered  AJAX  style  callbacks   –  all  security  se`ngs  inherited  from  web  host   •  Cross-­‐Domain   –  Web  APIs  and  clients  live  in  different  domains   •  na9ve  apps  (desktop,  mobile)   •  client  side  JavaScript  code  (browser)   –  web  API  specific  security  se`ngs  
  9. 11   @leastprivilege   Application Login Same-­‐Domain  Scenario   • 

    Web  APIs  inherit  security  se[ngs  of  web  host   –  e.g.  cookies,  Windows  authen9ca9on,  client  certs...   Pages Web APIs $.ajax  
  10. 12   @leastprivilege   Cross-­‐domain  Scenario   •  MulOtude  of

     scenarios   –  username/password  authen9ca9on  (w/  session  tokens)   –  integra9on  with  exis9ng  infrastructure  (e.g.  SAML)   –  OAuth2  style  authen9ca9on  &  authoriza9on  (e.g.  JWT   tokens)   –  CORS  restric9ons  for  JavaScript-­‐based  clients   •  No  built-­‐in  support  in  ASP.NET  Web  API   –  extensibility  enabled  via  message  handler  infrastructure   –  Thinktecture.Iden0tyModel  authen9ca9on  framework  
  11. 14   @leastprivilege   Message  handler   •  Gets  to

     see  all  requests  and  responses   •  Two  scopes   –  global  and  per-­‐route   public  class  MyHandler  :  DelegatingHandler   {          protected  async  override  Task<HttpResponseMessage>  SendAsync(              HttpRequestMessage  request,  CancellationToken  cancellationToken)          {                  //  inspect  request                      var  response  =  await  base.SendAsync(request,  cancellationToken);                    //  inspect  response                  return  response;          }   }  
  12. 15   @leastprivilege   Thinktecture.Iden9tyModel   hep://thinktecture.github.com/Thinktecture.Iden9tyModel.45/   AuthenticationHandler :

    DelegatingHandler Header Query String Client Certificate Cookie incoming  credenOal   mapping  credenOal   to  token  handler   1.  AuthenOcaOon   2.  Claims  TransformaOon   3.  (Session  handling)   4.  Set  Thread.CurrentPrincipal  
  13. 16   @leastprivilege   Scenario:  Username/Password   •  Typically  implemented

     using  HTTP  Basic  AuthenOcaOon   AuthorizaOon:        Basic  base64(username:password)   GET  /service/resource  
  14. 17   @leastprivilege   Example:  configuring  basic   authen9ca9on  

    var  authentication  =  new  AuthenticationConfiguration   {        //  set  claims  authentication  manager              ClaimsAuthenticationManager  =  new  ClaimsTransformer(), };   //  set  password  validator   authentication.AddBasicAuthentication((username,  password)                =>  UserCredentials.Validate(username,  password));   //  add  message  handler   config.MessageHandlers.Add(new  AuthenticationHandler(authentication));
  15. 18   @leastprivilege   Layering  session  tokens  on  top  of

      authen9ca9on   •  Useful  to  get  rid  of  passwords/keys  on  the  client   –  no  need  to  store  long  lived  secrets   AuthorizaOon:        Basic  base64(username:password)   GET  /service/resource/token   <session  token>   GET  /service/resource   AuthorizaOon:        Session  <session  token>  
  16. 19   @leastprivilege   Example:  configuring  session  tokens   var

     authentication  =  new  AuthenticationConfiguration     {        //  set  claims  authentication  manager        ClaimsAuthenticationManager  =  new  ClaimsTransformer(),        EnableSessionToken  =  true,          SessionToken  =  new  SessionTokenConfiguration          {              DefaultTokenLifetime  =  TimeSpan.FromDays(14),              SigningKey  =  GetSigningKey()        }   };       //  set  password  validator   authentication.AddBasicAuthentication((username,  password)                =>  UserCredentials.Validate(username,  password));       //  add  message  handler   config.MessageHandlers.Add(new  AuthenticationHandler(authentication));    
  17. 20   @leastprivilege   CORS   (Cross  Origin  Resource  Sharing)

      h?p://server1/client.htm   $.ajax(  ...  )   h?p://server2/service   ?   Data  
  18. 21   @leastprivilege   CORS  Sample   $.ajax(  ...  )

      Service   OPTIONS  /service     Access-­‐Control-­‐Request-­‐Method:  POST   Origin:  hep://server1   Access-­‐Control-­‐Allow-­‐Origin:  hep://server1   POST  /service  
  19. 22   @leastprivilege   Scenario:  Token-­‐based  Authen9ca9on    Client  

    Web  API   Security   Token   Service   1.   Request  token   2.  Send  token    Token    Authorization:  Bearer  <token>  
  20. 23   @leastprivilege   Token-­‐based  authen9ca9on   •  ExisOng  infrastructure

     typically  around   –  WS-­‐Federa9on  /  WS-­‐Trust   –  SAML  token/protocol   •  Not  directly  compaOble  with  web  API  world   –  SOAP  toolkit  with  WS-­‐*  support  needed   –  SAML  tokens  quite  heavy   •  Emerging  set  of  standards   –  OAuth2  framework   –  JSON  Web  Tokens  (JWT)  
  21. 24   @leastprivilege   Example:  SAML-­‐based  authen9ca9on   var  authentication

     =  new  AuthenticationConfiguration  {  …  }       //  set  SAML  validator   authentication.AddSaml2(          issuerThumbprint:  Constants.IdSrv.SigningCertThumbprint,          issuerName:  Constants.IdSrv.IssuerUri,          audienceUri:  Constants.Realm,          certificateValidator:  X509CertificateValidator.None,          options:  AuthenticationOptions.ForAuthorizationHeader("SAML"));     //  add  message  handler   config.MessageHandlers.Add(new  AuthenticationHandler(authentication));    
  22. 25   @leastprivilege   Scenario:  API  Backend  &  mul9ple  

    Clients   Web  API   AuthorizaOon  Server   1   2  
  23. 26   @leastprivilege   JSON  Web  Token  (JWT)   {

         "typ":  "JWT"      "alg":  "HS256"   }   {      "iss":  "http://myIssuer"      "exp":  "1340819380"      "aud":  "http://myResource"        "name":  "alice"      "role":  "foo,bar"   }   Header   Claims   eyJhbGciOiJub25lIn0.eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMD.4MTkzODAsDQogImh0dHA6Ly9leGFt   Header   Claims   Signature  
  24. 27   @leastprivilege   Example:  JWT-­‐based  authen9ca9on   var  authentication

     =  new  AuthenticationConfiguration  {  …  }       //  set  JWT  validator   authentication.AddJsonWebToken(          issuer:  Constants.IssuerUri,          audience:  Constants.Audience,          signingKey:  Constants.SigningKey,          options:  AuthenticationOptions.ForAuthorizationHeader("Bearer"));       //  add  message  handler   config.MessageHandlers.Add(new  AuthenticationHandler(authentication));    
  25. 29   @leastprivilege   Step  1a:  Authoriza9on  Request   Web

     Applica9on   (Client)   Authoriza9on  Server   Resource  Owner   GET  /authorize?      client_id=webapp&      redirect_uri=https://webapp/cb&      scope=resource&      response_type=code&      state=123  
  26. 30   @leastprivilege   Step  1b:  Authoriza9on  Response   Web

     Applica9on   (Client)   Authoriza9on  Server   Resource  Owner   GET  /cb?      code=xyz&      state=123  
  27. 31   @leastprivilege   Step  2a:  Token  Request   Web

     Applica9on   (Client)   Authoriza9on  Server   Resource  Owner   POST  /token    Authorization:  Basic  (client_id:secret)     grant_type=authorization_code&   authorization_code=xyz  
  28. 32   @leastprivilege   Step  2b:  Token  Response   Web

     Applica9on   (Client)   Authoriza9on  Server   Resource  Owner   {      "access_token"  :  "abc",      "expires_in"  :  "360",      "token_type"  :  "Bearer",      "refresh_token"  :  "xyz"       }  
  29. 33   @leastprivilege   Step  3:  Resource  Access   Web

     Applica9on   (Client)   Resource  Owner   GET  /resource      Authorization:  Bearer  access_token   Web  API  
  30. 34   @leastprivilege   (Step  4:  Refreshing  the  Token)  

    Web  Applica9on   (Client)   Resource  Owner   POST  /token    Authorization:  Basic  (client_id:secret)     grant_type=refresh_token&   refresh_token=xyz   Authoriza9on  Server  
  31. 38   @leastprivilege   Step  1a:  Authoriza9on  Request   Web

     API   Resource  Owner   Client   GET  /authorize?      client_id=nativeapp&      redirect_uri=http://localhost/cb&      scope=resource&      response_type=token&      state=123   Authoriza9on  Server  
  32. 39   @leastprivilege   Step  1b:  Authoriza9on  Response   Web

     API   Resource  Owner   Client   GET  /cb#      access_token=abc&      expires_in=3600&      state=123   Authoriza9on  Server  
  33. 40   @leastprivilege   Step  2:  Resource  Access   Web

     API   Resource  Owner   Client   GET  /resource      Authorization:          Bearer  access_token  
  34. 42   @leastprivilege   Step  1a:  Authoriza9on  Request   Web

     API   Resource  Owner   Client   Authoriza9on  Server   POST  /token    Authorization:  Basic  (client_id:secret)     grant_type=password&   scope=resource&   user_name=owner&   password=password&  
  35. 43   @leastprivilege   Step  1b:  Authoriza9on  Response   Web

     API   Resource  Owner   Client   Authoriza9on  Server   {      "access_token"  :  "abc",      "expires_in"  :  "360",      "token_type"  :  "Bearer",      "refresh_token"  :  "xyz"       }  
  36. 44   @leastprivilege   Step  2:  Resource  Access   Web

     API   Resource  Owner   Client   GET  /resource      Authorization:          Bearer  access_token  
  37. 45   @leastprivilege   Over/Under-­‐Pos9ng   public  class  Data  

    {          [Required]          public  string  Name  {  get;  set;  }            [Required]          public  string  Email  {  get;  set;  }            public  bool  isAdmin  {  get;  set;  }   }   public  DataController  :  ApiController   {          public  HttpResponseMessage  Post(Data  data)          {              if  (ModelState.IsValid)              {                    DataRepository.Add(data);              }          }   }  
  38. 46   @leastprivilege   Summary   •  HTTP  has  a

     very  simple  security  model   •  Correct  handling  of  SSL  is  paramount   •  ASP.NET  Web  API  is  a  thin  abstracOon  layer  over  HTTP   •  Password-­‐based  authenOcaOon  is  an  anO-­‐pa?ern   •  OAuth2  becomes  the  least  common  denominator   technology  for  cross-­‐plagorm  development