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

Zanechat odpověď

Vyplňte detaily níže nebo klikněte na ikonu pro přihlášení:

Logo WordPress.com

Komentujete pomocí vašeho WordPress.com účtu. Odhlásit /  Změnit )

Facebook photo

Komentujete pomocí vašeho Facebook účtu. Odhlásit /  Změnit )

Připojování k %s