Stored Procedures mit bestimmten Namen rekompilieren

Weil ich auch das immer wieder vergesse:

use MyDB

declare @proc varchar(50)

declare procs cursor for select SPECIFIC_NAME from INFORMATION_SCHEMA.ROUTINES where ROUTINE_TYPE='PROCEDURE' and SPECIFIC_NAME like '%whatever%'
open procs
fetch next from procs into @proc
while @@FETCH_STATUS = 0
begin
   print @proc
   exec sp_recompile @proc
   fetch next from procs into @proc
end
close procs
deallocate procs

Open with notepad

Weil ichs dauernd vergesse:

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\*\shell\Open with Notepad]

[HKEY_CLASSES_ROOT\*\shell\Open with Notepad\Command]
@="notepad \"%1\""

 

Mehr Cores für Android Emulator

Android Device Manager in Visual Studio 2017 legt Android Emulator VMs IMMER mit 2 Cores an – wo doch jeder weiß dass ein Android unter 4 Cores in Wahrheit unbenutzbar ist eine sehr fragwürdige Entscheidung. Die Emulatoren sind völlig überraschend schweinelangsam – und es gibt keinen Parameter wo man das easy raufstellen könnte.

Lösung: Emulator manuell starten mit Parameter -cores XX oder im Device Manager einen Custom Parameter namens hw.cpu.ncore hinzufügen und als Wert die gewünschten Cores angeben:

SMA Sunny Home Manager + Sunny Island an A1 Router

….schlechte Idee. Offenbar blockt der A1 Router (und vermutlich viele viele andere auch) Teile der Kommunikation zwischen Manager und Island (oder kann was nicht was dafür notwendig wäre, die Zauberwörter “IGMP Snooping” tauchen hier auf, mag aber auch was ganz andreas sein) – aber nicht 100% zuverlässig sodass es manchmal funktioniert und manchmal eben nicht.

Nach mehreren Stunden des mehr oder weniger erfolgreichen Probierens hat dann alles funktioniert – Reset probiert (um zu sehen was z.B. bei Stromausfall passiert) und (natürlich) war wieder alles weg und konnte nicht restauriert werden.

Aus reiner Verzweiflung dann einen dummen Switch für Manager und Island genommen, gegen Router uplinked und alles funktioniert auf Anhieb….irgendwann am Weg auch Island von DHCP auf statische Adresse umgestellt, keine Ahnung ob das mitwirkt, schaden tuts bei der Turboblackbox Manager sicher nicht. 😀

Hier konkret:
* Sunny Home Manager 2.0
* Sunny Island 6.0H-12

Zertifikatswechsel ADFS (3.0 / Service-Communication)

….weil die Konsole offenbar nicht immer das macht was sie soll:

  • neues Zertifikat importieren (nanonaned)
  • NT SERVICE\adfssrv auf private Key berechtigen (read), alternativ Service Account
  • Set-AdfsSslCertificate -Thumbprint xxxx
  • Kontrolle mit netsh http show sslcert
  • ADFS Service restarten

Setzen via Console hat die Config aber nicht die Bindings geändert, auch nach Reboot nicht, Set-AdfsCertificate -CertificateType Service-Communications detto.

Zertifikatswechsel Web Application Proxy (ADFS)

….wenn Set-WebApplicationProxySslCertificate nicht will (warum auch immer):

  • neues Zertifikat importieren (Überraschung!)
  • HKLM\Software\Microsoft\ADFS\ProxyConfigurationStatus von 2 (=konfiguriert) auf 1 (=nicht konfiguriert) setzen
  • mit Wizard neue Verbindung zu herstellen (Name=öffentlicher Name vom ADFS, Zertifikat ist klar, User wird nur für Herstellung der Verbindung benötigt)

    oder

  • Install-WebApplicationProxy -FederationServiceTrustCredential (get-credential) -FederationServiceName meinadfs.meinedomain.whatever -CertificateThumbprint xxx

Zertifikatswechsel Office WebApps Server wenns schon zu spät ist

….sprich es abgelaufen ist und das Service nicht mehr startet. Powershell und Set-OfficeWebAppsFarm funktioniert dann sinnigerweise ja nicht mehr.

Lösung:

  • neues Zertifikat importieren (völlig überraschend)
  • Friendly Name vergeben
  • Setting “CertificateName” in C:\ProgramData\Microsoft\OfficeWebApps\Data\FarmState\settings.xml auf den neuen Friendly Name ändern
  • Service starten
  • freuen

ASP.NET Core WebAPI Cheat Sheet

Visual Studio: ASP.NET Core project (empty oder WebAPI)

empty:

Startup.cs:

ConfigureServices: services.AddMvc()

Configure: app.UseMvc()

“Controllers” Ordner erzeugen

New item: API Controller Class, Base class auf ControllerBase ändern (weniger Intellisync)

 

ROUTING

Class Routing: [Route("bli/bla")] als Controllerklassenattribut wird allen Actions vorgestellt. [Controller] in der Route wird durch Klassenname (muss mit “Controller” enden) ohne “Controller” ersetzt.

Atrribute Routing: [HttpGet/Post/Put/Delete("route")] vor Methode.
{bli} = Parameter “bli” in Methode wird aus Route geholt
{bla:int} = Parameter “bla” in Methode wird als int aus Route geholt (nur dann wenns auch ein int ist)
{bla:string:minlength(7)} = Parameter “blu” in Methode wird als string aus Route geholt, String muss mind. 7 Zeichen lang sein
{foo?} = optionaler Parameter
{bar=4711} = Defaultwert (sonst 0 bei int und “” bei string)
{wtf:regex(^abc…xyz$)} = Route greift nur wenn regular Expression matched

https://docs.microsoft.com/en-us/aspnet/core/fundamentals/routing

 

MODEL BINDING

Parameter in Action vorangestellt [FromRoute] (default), [FromBody], [FromQuery], [FromForm], [FromHeader] zwingt ASP.NET Core gleichnamigen Parameter aus dieser Quelle zu beziehen.

Immer ModelState.IsValid prüfen um sicherzustellen dass alle Bindings und Contraints erfolgreich ausgewertet wurden.

DataAnnoations bei Properties von komplexen Typen (z.B. [MinLength(7)] public string Bli { get; set; } in einer Klasse) werden für ModelState ausgewertet (public und get/set sind notwendig!).

https://docs.microsoft.com/en-us/aspnet/core/mvc/models/validation

 

ACTION RESULTS

Actions liefern IActionResult anstatt Basistypen, ermöglicht clientseitig besseres Ergebnismanagement (v.a. im Fehlerfall – Exception würde sonst immer 500 liefern anstatt sinnvoller Informationen).

return NotFound()  = 404
return BadRequest() oder BadRequest(ModelState) = 400, alternativ mit Zusatzinformation (Validation-Fehler z.B.)
return Ok() oder Ok(“whatever”) oder Ok(new { bli=”bla”, blu=”blu”}) = 200 mit Wert im Body (Object wird zu JSON)

https://docs.microsoft.com/en-us/aspnet/core/web-api/action-return-types

 

SECURITY – TRANSPORT

Für MVC kann man verschiedenste Filter einfügen, zwei der wichtigsten (Antiforgery Token (eigentlich nicht Transport aber he…) und Require HTTPS gehen so) – in ConfigureServices():

services.AddMvc(options =>
{
   options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
   options.Filters.Add(new RequireHttpsAttribute());
});

In der Configure Methode der Startup-Klasse (Startup.cs) gibts vielfache Möglichkeiten die Transportsicherheit zu erhöhen:

app.UseHttpsRedirection() = offensichtlich
app.UseHsts() = offensichtlich

Das ist aber eher dürftig, viele zusätzliche Securityheader bekommt man über diverse Nugets:

Nwebsec.AspnetCore.Middleware (https://docs.nwebsec.com/en/latest/nwebsec/NWebsec.AspNetCore.Middleware.html)
app.UseHsts(options => options.MaxAge(days: 365).IncludeSubdomains()) = offensichtlich aber mit Parameter
app.UseXXssProtections(options => options.EnableWithBlockMode()) = Cross Side Scripting Header, mit Parameter
app.UseXcontentTypeOptions() = X-Content-Type-Options Header
app.UseXfo(options => options.Deny()) = X-Frame-Options Header
app.UseReferrerPolicy(opts => opts.NoReferrer()) = Referrer Policy
app.UseCsp(…crazy zeug…) = Content Security Policy, siehe Doku, vielfältigste Möglichkeiten sich selbst die Knie wegzuschießen

NetEscapades.AspnetCore.SecurityHeaders (https://andrewlock.net/adding-default-security-headers-in-asp-net-core/)
app.UseSecurityHeaders(new HeaderPolicyCollection().AddDefaultSecurityHeaders()) = für die die etwas schreibfauler sind 😀

 

SECURITY – AUTHENTICATION UND AUTHORIZATION

Am Beispiel ADFS – in ConfigureServices() Authentication enablen:

services.AddAuthentication(sharedOptions =>
  {
     sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
     sharedOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
     sharedOptions.DefaultChallengeScheme = WsFederationDefaults.AuthenticationScheme;
  }).AddWsFederation(options =>
     {
        options.MetadataAddress = "https://myadfs.mydomain.com/FederationMetadata/2007-06/FederationMetadata.xml";
        options.Wtrealm = "https://myrelyingpartytrust/";
     }).AddCookie(options =>
        {
           options.AccessDeniedPath = new PathString("/api/mycontroller/myaccessdeniedaction");
        });

Wobei der Relying Party Trust im ADFS natürlich entsprechend eingetragen werden muss (WS-Federation) und die entsprechenden Claims issued werden müssen. Wtrealm ist der Relying Party Trust Identifier.

Authorization kann schon am ADFS passieren (Issuance Authorization Rules) oder auf WebAPI Seite mit dem [Authorize] oder [AllowAnonymous]  Attribut gesetzt auf Klasse (Controller) oder Methode (Action). Gemeinsame Regeln kann man in Policies in ConfigureService() mit Name erzeugen

services.AddAuthorization(options =>
    {
       options.AddPolicy("MyPolicy", policy => policy.RequireClaim("http://schemas.xmlsoap.org/claims/Group", "MyAdminGroup"));
    });

und dann im Klassen/Methodenattribute verwenden ([Authorize(Policy="MyPolicy")])