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!

    View Slide

  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!

    View Slide

  3. 3  
    @leastprivilege  
    Agenda  
    •  HTTP  Security  
    •  ASP.NET  Web  API  Security  Overview  
    •  AuthenOcaOon  
    •  AuthorizaOon  
    •  OAuth2  
    •  Scenarios    

    View Slide

  4. 4  
    @leastprivilege  
    The  big  picture  
    HTTPS  
    Host  
    ASP.NET  Web  API  

    View Slide

  5. 5  
    @leastprivilege  
    Developers  &  SSL  

    View Slide

  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  

    View Slide

  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  

    View Slide

  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)  
           {  …  }  
    }  

    View Slide

  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  
           }  
    }  

    View Slide

  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  

    View Slide

  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  

    View Slide

  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  

    View Slide

  13. 13  
    @leastprivilege  
    Hos9ng  and  dispatcher  layer  

    View Slide

  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  SendAsync(  
               HttpRequestMessage  request,  CancellationToken  cancellationToken)  
           {  
                   //  inspect  request  
       
                   var  response  =  await  base.SendAsync(request,  cancellationToken);  
     
                   //  inspect  response  
                   return  response;  
           }  
    }  

    View Slide

  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  

    View Slide

  16. 16  
    @leastprivilege  
    Scenario:  Username/Password  
    •  Typically  implemented  using  HTTP  Basic  AuthenOcaOon  
    AuthorizaOon:    
       Basic  base64(username:password)  
    GET  /service/resource  

    View Slide

  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));

    View Slide

  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  
     
    GET  /service/resource  
    AuthorizaOon:    
       Session    

    View Slide

  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));    

    View Slide

  20. 20  
    @leastprivilege  
    CORS  
    (Cross  Origin  Resource  Sharing)  
    h?p://server1/client.htm  
    $.ajax(  ...  )  
    h?p://server2/service  
    ?  
    Data  

    View Slide

  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  

    View Slide

  22. 22  
    @leastprivilege  
    Scenario:  Token-­‐based  Authen9ca9on  
     Client   Web  API  
    Security  
    Token  
    Service  
    1.  
    Request  token  
    2.  Send  token  
     Token  
     Authorization:  Bearer    

    View Slide

  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)  

    View Slide

  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));    

    View Slide

  25. 25  
    @leastprivilege  
    Scenario:  API  Backend  &  mul9ple  
    Clients  
    Web  API  
    AuthorizaOon  Server  
    1  
    2  

    View Slide

  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  

    View Slide

  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));    

    View Slide

  28. 28  
    @leastprivilege  
    Example:  Server-­‐rendered  Applica9on  
    Web  Applica9on  
    (Client)  
    Web  API  
    Resource  Owner  

    View Slide

  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  

    View Slide

  30. 30  
    @leastprivilege  
    Step  1b:  Authoriza9on  Response  
    Web  Applica9on  
    (Client)  
    Authoriza9on  Server  
    Resource  Owner  
    GET  /cb?  
       code=xyz&  
       state=123  

    View Slide

  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  

    View Slide

  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"      
    }  

    View Slide

  33. 33  
    @leastprivilege  
    Step  3:  Resource  Access  
    Web  Applica9on  
    (Client)  
    Resource  Owner  
    GET  /resource  
     
     Authorization:  Bearer  access_token  
    Web  API  

    View Slide

  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  

    View Slide

  35. 35  
    @leastprivilege  
    Client  Management  (e.g.  Flickr)  

    View Slide

  36. 36  
    @leastprivilege  
    Client  Management  (e.g.  Dropbox)  

    View Slide

  37. 37  
    @leastprivilege  
    Example:  Na9ve/User-­‐Agent  based  
    Applica9on  
    Web  API  
    Resource  Owner   Client  

    View Slide

  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  

    View Slide

  39. 39  
    @leastprivilege  
    Step  1b:  Authoriza9on  Response  
    Web  API  
    Resource  Owner   Client  
    GET  /cb#  
       access_token=abc&  
       expires_in=3600&  
       state=123  
    Authoriza9on  Server  

    View Slide

  40. 40  
    @leastprivilege  
    Step  2:  Resource  Access  
    Web  API  
    Resource  Owner   Client  
    GET  /resource  
     
     Authorization:    
         Bearer  access_token  

    View Slide

  41. 41  
    @leastprivilege  
    Example:  Trusted  Applica9on  
    Web  API  
    Resource  Owner   Client  

    View Slide

  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&  

    View Slide

  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"      
    }  

    View Slide

  44. 44  
    @leastprivilege  
    Step  2:  Resource  Access  
    Web  API  
    Resource  Owner   Client  
    GET  /resource  
     
     Authorization:    
         Bearer  access_token  

    View Slide

  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);  
               }  
           }  
    }  

    View Slide

  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  

    View Slide