2024-11-25 14:29:42 +05:00
using System.Text.Json.Nodes ;
2024-11-25 10:09:38 +05:00
using Microsoft.AspNetCore.Authentication.JwtBearer ;
2024-11-20 15:22:23 +05:00
using Microsoft.IdentityModel.Tokens ;
using Microsoft.OpenApi.Any ;
using Microsoft.OpenApi.Models ;
2024-11-25 10:09:38 +05:00
using Persistence.Models.Configurations ;
2024-11-25 14:29:42 +05:00
using Swashbuckle.AspNetCore.SwaggerGen ;
2024-11-20 15:22:23 +05:00
namespace Persistence.API ;
public static class DependencyInjection
{
public static void AddSwagger ( this IServiceCollection services , IConfiguration configuration )
{
services . AddSwaggerGen ( c = >
{
c . MapType < TimeSpan > ( ( ) = > new OpenApiSchema { Type = "string" , Example = new OpenApiString ( "0.00:00:00" ) } ) ;
c . MapType < DateOnly > ( ( ) = > new OpenApiSchema { Type = "string" , Format = "date" } ) ;
c . MapType < JsonValue > ( ( ) = > new OpenApiSchema
{
AnyOf = new OpenApiSchema [ ]
{
new OpenApiSchema { Type = "string" , Format = "string" } ,
new OpenApiSchema { Type = "number" , Format = "int32" } ,
new OpenApiSchema { Type = "number" , Format = "float" } ,
}
} ) ;
c . CustomOperationIds ( e = >
{
return $"{e.ActionDescriptor.RouteValues[" action "]}" ;
} ) ;
c . SwaggerDoc ( "v1" , new OpenApiInfo { Title = "Persistence web api" , Version = "v1" } ) ;
2024-11-25 10:09:38 +05:00
var needUseKeyCloak = configuration . GetSection ( "NeedUseKeyCloak" ) . Get < bool > ( ) ;
2024-11-25 14:29:42 +05:00
if ( needUseKeyCloak )
c . AddKeycloackSecurity ( configuration ) ;
else c . AddDefaultSecurity ( configuration ) ;
2024-11-20 15:22:23 +05:00
2024-11-25 10:09:38 +05:00
//var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
//var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
//var includeControllerXmlComment = true;
2024-11-25 14:29:42 +05:00
//options.IncludeXmlComments(xmlPath, includeControllerXmlComment);
//options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, "AsbCloudApp.xml"), includeControllerXmlComment);
2024-11-25 10:09:38 +05:00
} ) ;
2024-11-20 15:22:23 +05:00
}
2024-11-25 14:29:42 +05:00
#region Authentication
public static void AddJWTAuthentication ( this IServiceCollection services , IConfiguration configuration )
2024-11-20 15:22:23 +05:00
{
2024-11-25 10:09:38 +05:00
var needUseKeyCloak = configuration
. GetSection ( "NeedUseKeyCloak" )
. Get < bool > ( ) ;
2024-11-25 14:29:42 +05:00
if ( needUseKeyCloak )
services . AddKeyCloakAuthentication ( configuration ) ;
else services . AddDefaultAuthentication ( configuration ) ;
}
private static void AddKeyCloakAuthentication ( this IServiceCollection services , IConfiguration configuration )
{
2024-11-27 17:59:37 +05:00
services . AddAuthentication ( JwtBearerDefaults . AuthenticationScheme )
2024-11-25 14:29:42 +05:00
. AddJwtBearer ( options = >
{
2024-11-25 10:09:38 +05:00
options . RequireHttpsMetadata = false ;
options . Audience = configuration [ "Authentication:Audience" ] ;
options . MetadataAddress = configuration [ "Authentication:MetadataAddress" ] ! ;
options . TokenValidationParameters = new TokenValidationParameters
2024-11-25 14:29:42 +05:00
{
ValidIssuer = configuration [ "Authentication:ValidIssuer" ] ,
} ;
2024-11-27 17:59:37 +05:00
} ) ;
2024-11-25 14:29:42 +05:00
}
private static void AddDefaultAuthentication ( this IServiceCollection services , IConfiguration configuration )
{
services . AddAuthentication ( JwtBearerDefaults . AuthenticationScheme )
2024-11-25 10:09:38 +05:00
. AddJwtBearer ( options = >
{
options . RequireHttpsMetadata = false ;
options . TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true ,
ValidIssuer = JwtParams . Issuer ,
ValidateAudience = true ,
ValidAudience = JwtParams . Audience ,
ValidateLifetime = true ,
IssuerSigningKey = JwtParams . SecurityKey ,
ValidateIssuerSigningKey = false
} ;
options . Events = new JwtBearerEvents
{
OnMessageReceived = context = >
{
var accessToken = context . Request . Headers [ "Authorization" ]
. ToString ( )
. Replace ( JwtBearerDefaults . AuthenticationScheme , string . Empty )
. Trim ( ) ;
context . Token = accessToken ;
return Task . CompletedTask ;
} ,
OnTokenValidated = context = >
{
var username = context . Principal ? . Claims
. FirstOrDefault ( e = > e . Type = = "username" ) ? . Value ;
var password = context . Principal ? . Claims
. FirstOrDefault ( e = > e . Type = = "password" ) ? . Value ;
var keyCloakUser = configuration
. GetSection ( nameof ( AuthUser ) )
. Get < AuthUser > ( ) ! ;
if ( username ! = keyCloakUser . Username | | password ! = keyCloakUser . Password )
{
context . Fail ( "username or password did not match" ) ;
}
return Task . CompletedTask ;
}
} ;
} ) ;
}
2024-11-25 14:29:42 +05:00
#endregion
#region Security ( Swagger )
private static void AddKeycloackSecurity ( this SwaggerGenOptions options , IConfiguration configuration )
{
options . AddSecurityDefinition ( "Keycloack" , new OpenApiSecurityScheme
{
Description = @"JWT Authorization header using the Bearer scheme. Enter 'Bearer' [space] and then your token in the text input below. Example: 'Bearer 12345abcdef'" ,
Name = "Authorization" ,
In = ParameterLocation . Header ,
Type = SecuritySchemeType . OAuth2 ,
Flows = new OpenApiOAuthFlows
{
Implicit = new OpenApiOAuthFlow
{
AuthorizationUrl = new Uri ( configuration [ "Authentication:AuthorizationUrl" ] ) ,
}
}
} ) ;
options . AddSecurityRequirement ( new OpenApiSecurityRequirement ( )
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType . SecurityScheme ,
Id = "Keycloack"
} ,
Scheme = "Bearer" ,
Name = "Bearer" ,
In = ParameterLocation . Header ,
} ,
new List < string > ( )
}
} ) ;
}
private static void AddDefaultSecurity ( this SwaggerGenOptions options , IConfiguration configuration )
{
options . AddSecurityDefinition ( "Bearer" , new OpenApiSecurityScheme
{
Description = @"JWT Authorization header using the Bearer scheme. Enter 'Bearer' [space] and then your token in the text input below. Example: 'Bearer 12345abcdef'" ,
Name = "Authorization" ,
In = ParameterLocation . Header ,
Type = SecuritySchemeType . ApiKey ,
Scheme = "Bearer" ,
} ) ;
options . AddSecurityRequirement ( new OpenApiSecurityRequirement ( )
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType . SecurityScheme ,
Id = "Bearer"
} ,
Scheme = "oauth2" ,
Name = "Bearer" ,
In = ParameterLocation . Header ,
} ,
new List < string > ( )
}
} ) ;
}
#endregion
2024-11-20 15:22:23 +05:00
}