Connect(); 2017 – přehled oznámených novinek

Od 15. do 17. listopadu proběhla online vývojářská konference Microsoft Connect(); 2017, která přinesla řadu zásadních oznámení a novinek. Pro základní orientaci přináším přehled těch nejdůležitějších. Záznamy jednotlivých session si můžete stále přehrát.

Visual Studio & Developer Productivity

https://blogs.msdn.microsoft.com/visualstudio/2017/11/15/the-latest-in-developer-productivity-and-app-experiences/

Team Foundation Server / Visual Studio Team Services

https://blogs.msdn.microsoft.com/bharry/2017/11/15/connect-announcements/

  • Team Foundation Server 2018 – final release. Přináší pro on-premise funkčnost, kterou již známe z onlinového VSTS:
    • Mobile work item experience – responsivní podoba TFS webu
    • Wiki – jednoduchá Wiki založená na GIT-repository s Markdown soubory (ála GitHub)
    • Git Forks – forking ála GitHub
    • GVFS – viz dále
    • Graphical release definition editor
    • Deployment groups
  • GVFS – Git Virtual File System – umožní efektivní práci s obrovskými repository (ála Windows source codes), kdy jsou na pracovní stanici staženy pouze minimální potřebné soubory a zbytek zůstává „virtuální“ a je stahován dle potřeby
  • Azure DevOps Projects – zjednodušeně řečeno onboarding wizzard pro Azure a VSTS, který pro různé typy projektů (.NET, Java, Node.js, Python, …) založí šablonu aplikace, GIT repo, CI/CD pipeline, atd.
  • YAML – Pipeline as code (public preview) – podpora YAML pro VSTS buildy – víceméně textová podoba vytváření build definic do VSTS.
  • Release management gates – možnost vytváření podmínek pro posun release do dalšího deployment prostředí, např. „žádné nové bugy“ (obecně libovolné Work Item Query), stav Azure Monitoru, či dle výsledku volání libovolného REST API či Azure Function.
  • VSTS Symbol Server (public preview)  – TFS (resp. zatím VSTS) se konečně stává symbol-serverem pro uchovávání a publikování PDB souborů. S každým buildem lze PDB symboly uchovat a následně je získávat do Visual Studia, Windows Debuggeru či jakoukoliv další potřebu.
  • Hosted MacOS Build Agents – ve VSTS se objevila možnost poslat build na Hosted MacOS agenta. Mimochodem je tam nově i Hosted Linux.
  • TFS data import service (general availability) – finální release služby pro import on-premise databáze TFS do online VSTS
  • VSTS CLI (public preview) – command-line tools pro VSTS a TFS, git-like commands, atp.

Data

  • Microsoft SQL Operations Studio (Preview) – odlehčená multiplatformní podoba SQL Server Management Studia
  • Azure Databricks (Preview) – Apache-Spark jako služba na Azure
  • Apache Cassandra API for Azure Cosmos DB (Preview) – jako další možnost připojení na Cosmos DB přibylo API dle Apache Cassandra.
  • Microsoft is joining the MariaDB Foundation – MariaDB – fork MySQL od jejího původního autora, získává podporu Microsoftu coby platinum sponzora tohoto open-source projektu. (Mimochodem věděli jste, že se obě tyto databáze vlastně jmenují po dceři jejich autora? MySQL není „moje“, ale švédská Maruška.)

Xamarin

https://blog.xamarin.com/xamarin-announcements-microsoft-connect-2017/

  • .NET Embedding
  • Xamarin.Forms 2.5
    • Xamarin.Forms Native Forms
    • Xamarin.Forms Layout Compression
    • Xamarin.Forms & XAML Standard
  • Xamarin Live Player
  • Xamarin Workbooks open-sourced

AI – Artificial Intelligence

Zaznělo mnoho dalších drobností a náznaků, spousta produktů releasovalo drobnější updates. Směřující myšlenky se točily rozhodně kolem AI.

TFS – Work Item Queries – záznam [Jiří Kanda, HAVIT Vzdělávací okénko 9.11.2017]

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

Dotčená témata:

  • Search work items
  • Queries Editor
  • @Me, @Today, @CurrentIteration
  • operátor Was Ever
  • Charts
  • Type of Queries – Flat List, Tree of Work Items, …

Quartz .NET – sekvenční zřetězení jobů [Martin Havel, HAVIT Vzdělávací okénko 2.11.2017]

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

Dotčená témata:

  • Co je Quartz
  • Sekvenční spouštění úloh
  • Tři způsoby, jak se zřetězením jobů vypořádat

 

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

NPM as a build tool – záznam [Vít Heřman, HAVIT Vzdělávací okénko 27. 4. 2017]

Záznam z interního vzdělávacího okénka HAVIT z 27.4.2017 je publikován na našem HAVIT YouTube Channel. Téma prezentoval Vít Heřman:

Dotčená témata:

  • Grunt
  • Gulp
  • Webpack
  • NPN
  • NPN scripts
  • Pre a post skripty

Napojení Swashbuckle/Swagger v ASP.NET Core aplikaci na Google OpenID Connect

Pokud máme API, které je s authentizací pomocí JWT (JwtBearer) a chceme pomocí Swashbuckle/Swaggeru naše API testovat, je možné se pomocí Swashbuckle/Swaggeru přihlásit a získaný token (id_token/JWT) předávat  do API automaticky.

Swashbuckle/Swagger má podporu pro OAuth2, nikoliv však pro OpenID Connect. Avšak implementace OAuth Googlu umožní získat id_token (JWT) pro OpenID Connect. Chce to však jeden trik v javascriptu, který vymění hodnotu response_type „token“ za „token id_token“.


public IServiceProvider ConfigureServices(IServiceCollection services)
{

...

services
.AddAuthentication(options => options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options => ... );

...

services.AddSwaggerGen(c =>
{
...

c.AddSecurityDefinition("oauth2", new OAuth2Scheme
{
Type = "oauth2",
Flow = "implicit",
AuthorizationUrl = "https://accounts.google.com/o/oauth2/v2/auth",
TokenUrl = "https://www.googleapis.com/oauth2/v4/token",
Scopes = new Dictionary<string, string>
{
{ "openid profile email", "Default scopes" }
}
});

c.OperationFilter<AuthorizeCheckOperationFilter>();
});

}

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)

{

app.UseSwaggerUI(c =>
{
// Swashbuckle/Swagger podporují jen OAuth. Pro OpenID Connect je potřeba namísto "response_type=token" posílat "response_type=token id_token". To zajistíme hackem v javascriptu.
// Google OAuth navíc vyžaduje parametr nonce, který je v hacku rovněž přidán.
c.InjectOnCompleteJavaScript("/swagger-ui-customization.js");

c.ConfigureOAuth2("client-id", "client-secret", "http://localhost:PORT/swagger/ui/o2c-html", "application-name");
c.SwaggerEndpoint("/swagger/current/swagger.json", "Current");
});

Třída AuthorizeCheckOperationFilter zajišťuje doplnění informací o security pro Swashbuckle/Swagger:


internal class AuthorizeCheckOperationFilter : IOperationFilter
{
public void Apply(Operation operation, OperationFilterContext context)
{
// Alternativní implementace: https://github.com/domaindrivendev/Swashbuckle/blob/master/Swashbuckle.Dummy.Core/SwaggerExtensions/AssignOAuth2SecurityRequirements.cs
// Check for authorize attribute
var hasAuthorize = context.ApiDescription.ControllerAttributes().OfType<AuthorizeAttribute>().Any() || context.ApiDescription.ActionAttributes().OfType<AuthorizeAttribute>().Any();


if (hasAuthorize)
{
// přidá do dokumentace možnou odpověd - 401
operation.Responses.Add("401", new Response { Description = "Unauthorized" });

// přidá informaci o tom, že se má použít pro volání metody authentizační token (zobrazí se červený vykřičník)
operation.Security = new List<IDictionary<string, IEnumerable<string>>>
{
new Dictionary<string, IEnumerable<string>>
{
{ "oauth2", new string[] { "openid profile email" } }
}
};
}
}
}

Dále je potřeba do rootu webu umístit soubor swagger-ui-customization.js, který provádí ukrutný hack nad window.open:


// Swagger UI does not support custom response_type parameters. Azure Active Directory requires an 'id_token' value to
// be passed instead of 'token' (See https://github.com/swagger-api/swagger-ui/issues/1974).
window.swaggerUiAuth = window.swaggerUiAuth || {};
window.swaggerUiAuth.tokenName = 'id_token';

if (!window.isOpenReplaced) {
window.open = function (open) {
return function (url) {
url = url.replace('response_type=token', 'response_type=token%20id_token&nonce=456');
console.log(url);
return open.call(window, url);
};
}(window.open);
window.isOpenReplaced = true;
}

Moderní přístup k JavaScriptu – záznam [Pavel Kříž, HAVIT Vzdělávací okénko 12.10.2017]

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

Dotčená témata:

  • Transpillers – TypeScript, Babel
  • Flow, ESLint, TSlint,
  • Literal Objects
  • Revealing Module Pattern
  • CommonJS
  • AMD – Asynchronous Module Definition
  • Modules
  • Array
  • Event Loop
  • Asynchronní operace v JS
  • Promise
  • TypeScript – async/await, class, arrow,

Pattern matching – od C# k F# – záznam [Martin Havel, HAVIT Vzdělávací okénko 5.10.2017]

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

Dotčená témata:

  • funkcionální programování
  • geneze projektu kalkulačky v F#

ASP.NET Core Intro – záznam [Jiří Kanda, HAVIT Vzdělávací okénko 21.9.2017]

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

Dotčená témata:

  • Web vs WebAPI vs. Frontend
  • SSR – Server-side Rendering
  • ASP.NET Core vs. .NET Standard
  • Struktura projektu
  • Startup.cs
  • Program.cs