Securing (ASP.NET) Web API Architectures

Securing (ASP.NET) Web API Architectures

75681814fbbb90c9224ea5ed0f8324ee?s=128

Dominick Baier

March 03, 2013
Tweet

Transcript

  1. 1.

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

      h?p://leastprivilege.com   @leastprivilege   think mobile!
  2. 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   •  dominick.baier@thinktecture.com   •  h?p://leastprivilege.com   think mobile!
  3. 3.

    3   @leastprivilege   Agenda   •  HTTP  Security  

    •  ASP.NET  Web  API  Security  Overview   •  AuthenOcaOon   •  AuthorizaOon   •  OAuth2   •  Scenarios    
  4. 6.

    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.

    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.

    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.

    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.

    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.

    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.

    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.

    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.

    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.

    16   @leastprivilege   Scenario:  Username/Password   •  Typically  implemented

     using  HTTP  Basic  AuthenOcaOon   AuthorizaOon:        Basic  base64(username:password)   GET  /service/resource  
  14. 17.

    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.

    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.

    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.

    20   @leastprivilege   CORS   (Cross  Origin  Resource  Sharing)

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

    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.

    22   @leastprivilege   Scenario:  Token-­‐based  Authen9ca9on    Client  

    Web  API   Security   Token   Service   1.   Request  token   2.  Send  token    Token    Authorization:  Bearer  <token>  
  20. 23.

    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.

    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.

    25   @leastprivilege   Scenario:  API  Backend  &  mul9ple  

    Clients   Web  API   AuthorizaOon  Server   1   2  
  23. 26.

    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.

    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.

    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.

    30   @leastprivilege   Step  1b:  Authoriza9on  Response   Web

     Applica9on   (Client)   Authoriza9on  Server   Resource  Owner   GET  /cb?      code=xyz&      state=123  
  27. 31.

    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.

    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.

    33   @leastprivilege   Step  3:  Resource  Access   Web

     Applica9on   (Client)   Resource  Owner   GET  /resource      Authorization:  Bearer  access_token   Web  API  
  30. 34.

    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.

    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.

    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.

    40   @leastprivilege   Step  2:  Resource  Access   Web

     API   Resource  Owner   Client   GET  /resource      Authorization:          Bearer  access_token  
  34. 42.

    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.

    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.

    44   @leastprivilege   Step  2:  Resource  Access   Web

     API   Resource  Owner   Client   GET  /resource      Authorization:          Bearer  access_token  
  37. 45.

    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.

    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