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
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:
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;
};
});
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:
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:
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;
}
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:
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:
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:
Záznam z interního vzdělávacího okénka HAVIT ze 17.8.2017 je publikován na našem HAVIT YouTube Channel. Téma prezentoval Pavel Kříž:
Dotčená témata:
Záznam z interního vzdělávacího okénka HAVIT z 21.9.2017, kde nám Jiří Kanda připomenul základy TCP/IP. Záznam je publikován na našem HAVIT YouTube Channel:
Dotčená témata: