Category Archives: ASP.NET Core

Microsoft Developer Days Praha 2018 & Azure DevOps Bootcamp – záznamy z přednášek

Dne 12. listopadu 2018 jsme společně s Microsoftem pořádali vývojářskou konferenci Microsoft Developer Days Praha 2018 & Azure DevOps Bootcamp.

Na našem HAVIT YouTube Channelu vám nabízíme záznamy z většiny prezentací.

Microsoft Developer Days Praha 2018 & Azure DevOps Bootcamp – YouTube playlist:

  1. Keynote: Novinky v .NET 4.8, .NET Core 2.2 a 3.0, C# 8.0 a VS2019 [Robert Haken]
  2. Převod aplikací do kontejnerů [Tomáš Herceg]
  3. Diagnostika pádu ASP.NET Core aplikací [Mirek Holec]
  4. Azure DevOps a GitHub při vývoji DotVVM [Tomáš Herceg]
  5. Azure DevOps Services – pohled do kuchyně HAVIT [Jiří Kanda]
  6. Web Apps in Azure [Jan Hájek]

…toť z ročníku 2018 vše. Ostatní záznamy se buď nepodařily technicky, nebo si přednášející nepřál nahrávání. Od některých přednášek bude k dispozici alternativní záznam na webu WUG.cz s „kamerovým okénkem“.

ASP.NET Core Razor Pages – záznam [Mirek Holec, HAVIT Vzdělávací okénko 7.6.2018]

Záznam ze Vzdělávacího okénka HAVIT ze 7. června 2018, kde Mirek Holec prezentoval přehled ASP.NET Razor Pages:

  • Co jsou Razor Pages
  • Klíčové aspekty (Razor views, PageModel, Routing, Konvence, …)
  • Ukázka aplikace
  • Celkové shrnutí

Nahrávka je publikována na našem HAVIT YouTube Channelu.

ASP.NET Core včera, dnes a zítra [Miroslav Holec, HAVIT Vzdělávací okénko 3.5.2018]

Záznam ze Vzdělávacího okénka HAVIT z 3. května 2018, kde Miroslav Holec prezentoval historii [ASP].NET Core a chystaných novinkách ve verzi 2.1. Nahrávka je publikována na našem HAVIT YouTube Channelu.

Textovou podobu informací najdete na Mirkovo blogu:

CORS a WebAPI

V rámci solution máme dva webové projekty – Web (javascriptová single-page aplikace) a WebAPI (backend s API). v ASP.NET Core 2.0. Řešili jsme problém, že nám nefungoval spolehlivě CORS – javascriptové requesty z Webu nedostávaly správné odpovědi od WebAPI. Chovalo se to velmi podivně i přesto, že lokálně vše fungovalo, a to i když aplikace běžely na různých portech.

Konkrétně:

  • Některé GET requesty fungovaly i v testovacím prostředí, ale POST, PUT a DELETE requesty nikdy.
  • GET requesty browser někdy zdvojoval (zejména v Safari na Macu), první vždy prošel (status code 200) a druhý neprošel (status code 403)
  • V Developer tools v Chrome, ani v Safari nejsou vidět autorizační hlavičky i přesto, že uživatel je přihlášený (při odchycení requestu Fiddlerem tam skutečně jsou). Ovšem na localhostu jsou vidět autorizační hlavičky vždy.

CORS v aplikaci máme nastaven celkem standardně a nepříliš restriktivně:

2018-04-10-CORS-settings

Kde byl(y) problém(y):

Nejdříve jsme neměli povolené všechny hlavičky (pozor zejména na Authorization, která není v Chrome Developer tools defaultně vidět). Nakonec jsme stejně skočili u AllowAnyHeader().

Důležité je mít povoleno AllowCredentials(), pokud řešíte přihlašování

Na co nám nejdéle trvalo přijít je, že je potřeba povolit anonymní autentifikaci i když v aplikaci žádné anonymní požadavky nejsou potřeba (povoluje se to v IIS na obrázku níže). Je potřeba na to ovšem myslet a v aplikaci si ošetřit, že uživatel musí být přihlášen při běžném přístupu do aplikace.

2018-04-10-CORS-IIS

Na pozadí CORS funguje tak, že vzdálený klient nejdříve udělá tzv. preflight request metodou OPTIONS a v hlavičce pošle informace, na jakou URL chce jakou metodou kdo přistupovat. Pokud není povolena anonymní autentifikace, OPTIONS požadavek selže (vrátí 401), protože v hlavičce preflight requestu se dle specifikace https://fetch.spec.whatwg.org/#cors-preflight-fetch autorizační hlavička neposílá. V takovém případě vzdálený klient není schopný zjistit, zda bude mít oprávnění udělat skutečný požadavek, a tak celá komunikace selže (nebo se chová nepředvídatelně – viz podivnosti výše).

Technické podrobnosti např. zde: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS

Nakonec pro přehlednost ještě schéma posílání CORS požadavků:2018-04-10-CORS-schema

ASP.NET Core Security – CookieAuthentication vs. status code 401

Při použití cookie authentizace z nuget balíčku Microsoft.AspNetCore.Authentication.Cookies 2.0.0 odpovídá server na požadavky nepřihlášených uživatelů se status code 302 (redirect na přihlášení). Pohledem do zdrojových kódů zjistíme, že je to trochu složitější – status kód je 302 nebo 401:


public Func<RedirectContext<CookieAuthenticationOptions>, Task> OnRedirectToLogin { get; set; } = context =>
{
  if (IsAjaxRequest(context.Request))
  {
     context.Response.Headers["Location"] = context.RedirectUri;
    context.Response.StatusCode = 401;
  }
  else
  {
    context.Response.Redirect(context.RedirectUri);
  }
  return Task.CompletedTask;
};

private static bool IsAjaxRequest(HttpRequest request)
{
  return string.Equals(request.Query["X-Requested-With"], "XMLHttpRequest", StringComparison.Ordinal) ||
  string.Equals(request.Headers["X-Requested-With"], "XMLHttpRequest", StringComparison.Ordinal);
}

Takže odpověd je různá pro ajax requesty a ostatní. Přičemž ajax request je rozpoznáván dle hlavičky requestu. Pro cross domain požadavky se tato hlavička nepoužívá, pokud není pomocí CORS nastaveno jinak.

Pokud bychom chtěli návratovou hodnotu vždy 401 (a nikdy 302), lze to řešit jednoduchou úpravou:


services. ... .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options =>
{
  // Vestavěná metoda OnRedirectToLogin rozlišuje Ajaxové a ostatní requesty. Pro Ajaxové se vrací 401, pro ostatní 302 (Redirect).
  // Rozlišení requestů je dáno existencí hlavičky X-Requested-With, avšak ta se v cross domain requestech neposílá.
  // Proto metodu nahrazujeme tak, aby vždy vracela 401.
  options.Events.OnRedirectToLogin = context =>
  {
    context.Response.StatusCode = 401;
    return Task.CompletedTask;
  };
});

 

Hackování webů běžnými „smrtelníky“ – záznam [Jiří Kanda, HAVIT Vzdělávací okénko 19.10.2017]

Záznam z interního vzdělávacího okénka HAVIT z 19.10.2017 je publikován na našem HAVIT YouTube Channel. Téma prezentoval Jiří Kanda:

Dotčená témata:

  • Open Redirects
  • XSS – Cross Site Scripting, ASP.NET Request Validation
  • MIME-type injection
  • External JS references, CDN, Tag Managers
  • Cross Site Request Forgery (XSRF/CSRF)
  • CORS – Cross Origin Resource Sharing, Preflight requests
  • X-Frame-Options
  • X-Content-Type-Options
  • X-XSS-Protection