Adding authentication and authorization flow

This commit is contained in:
2025-02-26 22:23:15 +01:00
parent 176f149be3
commit 76779afd2e
22 changed files with 562 additions and 19 deletions

View File

@@ -21,6 +21,21 @@
"Name": "MIT License", "Name": "MIT License",
"Url": "https://github.com/csimonapastore/BasicDotnetTemplate/blob/main/LICENSE.md" "Url": "https://github.com/csimonapastore/BasicDotnetTemplate/blob/main/LICENSE.md"
} }
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"JWTSettings": {
"ValidAudience": "http://localhost:4200",
"ValidIssuer": "http://localhost:5000",
"Secret": "JWTAuthenticationHIGHsecuredPasswordVVVp1OH7Xzyr",
"ExpiredAfterMinsOfInactivity": 15
},
"EncryptionSettings": {
"Salt": "S7VIidfXQf1tOQYX"
} }
} }

View File

@@ -0,0 +1,42 @@
{
"AppSettings" :
{
"Settings": {
"Name": "MainProject",
"Version": "v1.0",
"Description": "This template contains basic configuration for a .Net 8 backend"
},
"DatabaseSettings": {
"SqlServerConnectionString": "SQLSERVER_DB_SERVER",
"MongoDbConnectionString": "MONGO_DB_SERVER",
"PostgreSQLConnectionString": "POSTGRESQL_DB_SERVER"
},
"OpenApiSettings": {
"TermsOfServiceUrl": "",
"OpenApiContact": {
"Name": "",
"Url": ""
},
"OpenApiLicense": {
"Name": "MIT License",
"Url": "https://github.com/csimonapastore/BasicDotnetTemplate/blob/main/LICENSE.md"
}
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"JWTSettings": {
"ValidAudience": "http://localhost:4200",
"ValidIssuer": "http://localhost:5000",
"Secret": "JWTAuthenticationHIGHsecuredPasswordVVVp1OH7Xzyr",
"ExpiredAfterMinsOfInactivity": 15
},
"EncryptionSettings": {
"Salt": "AAAAA"
}
}
}

View File

@@ -0,0 +1,108 @@
using System;
using BasicDotnetTemplate.MainProject.Models.Settings;
using Microsoft.AspNetCore.Builder;
using BasicDotnetTemplate.MainProject.Utils;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
namespace BasicDotnetTemplate.MainProject.Tests;
[TestClass]
public class CryptoUtils_Tests
{
[TestMethod]
public void Decrypt_Success()
{
try
{
string encryptedData = "d2ejdI1f4GYpq2kTB1nmeQkZXqR3QSxH8Yqkl7iv7zgfQ13qG/0dUUsreG/WGHWRBE5mVWaV43A=";
WebApplicationBuilder builder = WebApplication.CreateBuilder(Array.Empty<string>());
AppSettings appSettings = ProgramUtils.AddConfiguration(ref builder, System.AppDomain.CurrentDomain.BaseDirectory + "/JsonData");
CryptUtils cryptoUtils = new CryptUtils(appSettings);
var decryptedData = cryptoUtils.Decrypt(encryptedData);
var isEqual = decryptedData == "ThisIsASuccessfullTest";
Assert.IsTrue(isEqual);
}
catch (Exception ex)
{
Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}");
}
}
[TestMethod]
public void Decrypt_Error()
{
try
{
string encryptedData = "d1ejdI1f4GYpq2kTB1nmeQkZXqR3QSxH8Yqkl7iv7zgfQ13qG/0dUUsreG/WGHWRBE5mVWaV43A=";
WebApplicationBuilder builder = WebApplication.CreateBuilder(Array.Empty<string>());
AppSettings appSettings = ProgramUtils.AddConfiguration(ref builder, System.AppDomain.CurrentDomain.BaseDirectory + "/JsonData");
CryptUtils cryptoUtils = new CryptUtils(appSettings);
var decryptedData = cryptoUtils.Decrypt(encryptedData);
var isEqual = decryptedData == "ThisIsASuccessfullTest";
Assert.IsFalse(isEqual);
}
catch (Exception ex)
{
Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}");
}
}
[TestMethod]
public void Decrypt_ArgumentException()
{
try
{
string encryptedData = "d1ejdI1f4GYpq2kTB1nmeQkZXqR3QSxH8Yqkl7iv7zgfQ13qG/0dUUsreG/WGHWRBE5mVWaV43A=";
WebApplicationBuilder builder = WebApplication.CreateBuilder(Array.Empty<string>());
AppSettings appSettings = ProgramUtils.AddConfiguration(ref builder, System.AppDomain.CurrentDomain.BaseDirectory + "/JsonData", "invalidCryptAppsettings.json");
CryptUtils cryptoUtils = new CryptUtils(appSettings);
try
{
var decryptedData = cryptoUtils.Decrypt(encryptedData);
Assert.Fail($"Expected exception instead of response: {decryptedData}");
}
catch (ArgumentException argumentException)
{
Assert.IsInstanceOfType(argumentException, typeof(ArgumentException));
}
catch (Exception exception)
{
Assert.IsInstanceOfType(exception, typeof(ArgumentException));
}
}
catch (Exception ex)
{
Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}");
}
}
[TestMethod]
public void Decrypt_Empty()
{
try
{
string encryptedData = "WGHWRBE5mVWaV=";
WebApplicationBuilder builder = WebApplication.CreateBuilder(Array.Empty<string>());
AppSettings appSettings = ProgramUtils.AddConfiguration(ref builder, System.AppDomain.CurrentDomain.BaseDirectory + "/JsonData");
CryptUtils cryptoUtils = new CryptUtils(appSettings);
var decryptedData = cryptoUtils.Decrypt(encryptedData);
var isEqual = decryptedData == String.Empty;
Assert.IsTrue(isEqual);
}
catch (Exception ex)
{
Console.WriteLine(ex.InnerException);
Assert.Fail($"An exception was thrown: {ex.Message}");
}
}
}

View File

@@ -1,11 +1,3 @@
using System;
using System.Reflection;
using System.Net;
using System.Net.Http;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using BasicDotnetTemplate.MainProject;
using BasicDotnetTemplate.MainProject.Models.Api.Response;
using Microsoft.Extensions.DependencyModel.Resolution;
using BasicDotnetTemplate.MainProject.Models.Settings; using BasicDotnetTemplate.MainProject.Models.Settings;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using BasicDotnetTemplate.MainProject.Utils; using BasicDotnetTemplate.MainProject.Utils;

View File

@@ -0,0 +1,62 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using BasicDotnetTemplate.MainProject.Core.Attributes;
using BasicDotnetTemplate.MainProject.Models.Api.Request.Auth;
using BasicDotnetTemplate.MainProject.Models.Api.Response;
using BasicDotnetTemplate.MainProject.Services;
namespace BasicDotnetTemplate.MainProject.Controllers
{
[Route("[controller]")]
public class AuthController : BaseController
{
private IAuthService _authService;
public AuthController(
IConfiguration configuration,
IAuthService authService
) : base(configuration)
{
this._authService = authService;
}
[HttpPost("authenticate")]
[ProducesResponseType<string>(StatusCodes.Status200OK)]
[ProducesResponseType<BaseResponse>(StatusCodes.Status404NotFound)]
[ProducesResponseType<BaseResponse>(StatusCodes.Status400BadRequest)]
[ProducesResponseType<BaseResponse>(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> AuthenticateAsync([FromBody] AuthenticateRequest request)
{
try
{
if (
request == null ||
request.Data == null ||
String.IsNullOrEmpty(request.Data.Username) ||
String.IsNullOrEmpty(request.Data.Password)
)
{
return BadRequest("Request is not well formed");
}
var data = await this._authService.AuthenticateAsync(request.Data);
if (data == null)
{
return NotFound();
}
return Success(String.Empty, data);
}
catch (Exception exception)
{
var message = "Something went wrong";
if (!String.IsNullOrEmpty(exception?.Message))
{
message += $". {exception?.Message}";
}
return InternalServerError(message);
}
}
}
}

View File

@@ -37,6 +37,12 @@ namespace BasicDotnetTemplate.MainProject.Controllers
return StatusCode((int)HttpStatusCode.OK, CreateResponse(HttpStatusCode.OK, message, data)); return StatusCode((int)HttpStatusCode.OK, CreateResponse(HttpStatusCode.OK, message, data));
} }
protected IActionResult NotModified(string message, object? data = null)
{
message = String.IsNullOrEmpty(message) ? "Not modified" : message;
return StatusCode((int)HttpStatusCode.NotModified, CreateResponse(HttpStatusCode.NotModified, message, data));
}
protected IActionResult NotFound(string message, object? data = null) protected IActionResult NotFound(string message, object? data = null)
{ {
message = String.IsNullOrEmpty(message) ? "Not found" : message; message = String.IsNullOrEmpty(message) ? "Not found" : message;

View File

@@ -0,0 +1,32 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
using System;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Text;
using Microsoft.AspNetCore.Authorization;
namespace BasicDotnetTemplate.MainProject.Core.Attributes
{
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public class JwtAuthorizationAttribute : Attribute, IAuthorizationFilter
{
private readonly string? _policyName;
public JwtAuthorizationAttribute() { }
public JwtAuthorizationAttribute(string policyName)
{
_policyName = policyName;
}
public void OnAuthorization(AuthorizationFilterContext context)
{
return;
}
}
}

View File

@@ -2,6 +2,7 @@
<PropertyGroup> <PropertyGroup>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<Configuration>Debug</Configuration>
<TargetFramework>net8.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
@@ -13,18 +14,22 @@
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.AspNetCore" Version="2.2.0" /> <PackageReference Include="Microsoft.AspNetCore" Version="2.2.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.1" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.13" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Abstractions" Version="9.0.1" /> <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="8.0.13" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.8"> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Abstractions" Version="9.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.8" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="9.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.8"> <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="9.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="9.0.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" /> <PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="Microsoft.Identity.Web" Version="3.7.1" />
<PackageReference Include="MongoDB.Driver" Version="2.28.0" /> <PackageReference Include="MongoDB.Driver" Version="2.28.0" />
<PackageReference Include="MongoDB.EntityFrameworkCore" Version="8.1.0" /> <PackageReference Include="MongoDB.EntityFrameworkCore" Version="8.1.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />

View File

@@ -0,0 +1,9 @@
namespace BasicDotnetTemplate.MainProject.Models.Api.Common.Role;
public class UserRole
{
#nullable enable
public string? Guid { get; set; }
public string? Name { get; set; }
#nullable disable
}

View File

@@ -0,0 +1,19 @@
using BasicDotnetTemplate.MainProject.Models.Api.Common.Role;
namespace BasicDotnetTemplate.MainProject.Models.Api.Common.User;
public class AuthenticatedUser
{
#nullable enable
public string? Guid { get; set; }
public string? Username { get; set; }
public string? FirstName { get; set; }
public string? LastName { get; set; }
public string? Email { get; set; }
public UserRole? Role { get; set; }
#nullable disable
}

View File

@@ -0,0 +1,13 @@
namespace BasicDotnetTemplate.MainProject.Models.Api.Data.Auth;
public class AuthenticateRequestData
{
#nullable enable
public string? Username { get; set; }
public string? Password { get; set; }
#nullable disable
}

View File

@@ -0,0 +1,14 @@
using BasicDotnetTemplate.MainProject.Models.Api.Data.Auth;
namespace BasicDotnetTemplate.MainProject.Models.Api.Request.Auth;
public class AuthenticateRequest
{
#nullable enable
public AuthenticateRequestData? Data { get; set; }
#nullable disable
}

View File

@@ -3,6 +3,7 @@ namespace BasicDotnetTemplate.MainProject.Models.Database.SqlServer
public class Base public class Base
{ {
public int Id { get; set; } public int Id { get; set; }
public string Guid { get; set; }
public DateTime CreationTime { get; set; } public DateTime CreationTime { get; set; }
public int CreationUserId { get; set; } public int CreationUserId { get; set; }
public DateTime UpdateTime { get; set; } public DateTime UpdateTime { get; set; }

View File

@@ -7,6 +7,8 @@ public class AppSettings
public PrivateSettings? PrivateSettings { get; set; } public PrivateSettings? PrivateSettings { get; set; }
public OpenApiSettings? OpenApiSettings { get; set; } public OpenApiSettings? OpenApiSettings { get; set; }
public DatabaseSettings? DatabaseSettings { get; set; } public DatabaseSettings? DatabaseSettings { get; set; }
public JWTSettings? JWTSettings { get; set; }
public EncryptionSettings? EncryptionSettings { get; set; }
#nullable disable #nullable disable
} }

View File

@@ -0,0 +1,8 @@
namespace BasicDotnetTemplate.MainProject.Models.Settings;
public class EncryptionSettings
{
#nullable enable
public string? Salt { get; set; }
#nullable disable
}

View File

@@ -0,0 +1,12 @@
namespace BasicDotnetTemplate.MainProject.Models.Settings;
public class JWTSettings
{
#nullable enable
public string? ValidAudience { get; set; }
public string? ValidIssuer { get; set; }
public string? Secret { get; set; }
public int? ExpiredAfterMinsOfInactivity { get; set; }
#nullable disable
}

View File

@@ -0,0 +1,38 @@
using BasicDotnetTemplate.MainProject.Models.Api.Data.Auth;
using BasicDotnetTemplate.MainProject.Models.Api.Common.User;
using BasicDotnetTemplate.MainProject.Utils;
namespace BasicDotnetTemplate.MainProject.Services;
public interface IAuthService
{
Task<AuthenticatedUser?> AuthenticateAsync(AuthenticateRequestData data);
}
public class AuthService : BaseService, IAuthService
{
protected CryptUtils _cryptUtils;
public AuthService(
IConfiguration configuration
) : base(configuration)
{
_cryptUtils = new CryptUtils(_appSettings);
}
public async Task<AuthenticatedUser?> AuthenticateAsync(AuthenticateRequestData data)
{
AuthenticatedUser? authenticatedUser = null;
var decryptedUsername = _cryptUtils.Decrypt(data.Username ?? String.Empty);
var decryptedPassword = _cryptUtils.Decrypt(data.Password ?? String.Empty);
if (!String.IsNullOrEmpty(decryptedUsername) && !String.IsNullOrEmpty(decryptedPassword))
{
}
return authenticatedUser;
}
}

View File

@@ -0,0 +1,24 @@
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using BasicDotnetTemplate.MainProject.Models.Settings;
namespace BasicDotnetTemplate.MainProject.Services;
public class BaseService
{
protected readonly IConfiguration _configuration;
protected readonly AppSettings _appSettings;
public BaseService(IConfiguration configuration)
{
_configuration = configuration;
_appSettings = new AppSettings();
_configuration.GetSection("AppSettings").Bind(_appSettings);
}
}

View File

@@ -0,0 +1,32 @@
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
namespace BasicDotnetTemplate.MainProject.Services;
public interface IJwtService
{
}
public class JwtService : BaseService, IJwtService
{
private readonly string _jwtKey;
private readonly string _jwtIssuer;
private readonly string _jwtAudience;
public JwtService(
IConfiguration configuration
) : base(configuration)
{
_jwtKey = _appSettings?.JWTSettings?.Secret ?? String.Empty;
_jwtIssuer = _appSettings?.JWTSettings?.ValidIssuer ?? String.Empty;
_jwtAudience = _appSettings?.JWTSettings?.ValidAudience ?? String.Empty;
}
}

View File

@@ -0,0 +1,59 @@
using System;
using System.Security.Cryptography;
using System.Text;
using BasicDotnetTemplate.MainProject.Models.Settings;
namespace BasicDotnetTemplate.MainProject.Utils;
public class CryptUtils
{
private readonly string secretKey;
private const int M = 16;
private const int N = 32;
private readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
public CryptUtils(AppSettings appSettings)
{
secretKey = appSettings.EncryptionSettings?.Salt ?? String.Empty;
}
public string Decrypt(string encryptedData)
{
var decrypted = String.Empty;
if (String.IsNullOrEmpty(this.secretKey) || this.secretKey.Length < M)
{
throw new ArgumentException("Unable to proceed with decryption due to invalid settings");
}
if (!String.IsNullOrEmpty(encryptedData) && encryptedData.Length > N)
{
var iv = encryptedData.Substring(0, M);
var cipherText = encryptedData.Substring(N);
var fullCipher = Convert.FromBase64String(cipherText);
using (var aes = Aes.Create())
{
aes.Key = Encoding.UTF8.GetBytes(this.secretKey);
aes.IV = Encoding.UTF8.GetBytes(iv);
using (var decryptor = aes.CreateDecryptor(aes.Key, aes.IV))
{
using (var msDecrypt = new MemoryStream(fullCipher))
{
using (var cryptoStream = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (var srDecrypt = new StreamReader(cryptoStream))
{
decrypted = srDecrypt.ReadToEnd();
}
}
}
}
}
}
return decrypted;
}
}

View File

@@ -4,6 +4,7 @@ using MongoDB.Driver;
using NLog; using NLog;
using BasicDotnetTemplate.MainProject.Core.Database; using BasicDotnetTemplate.MainProject.Core.Database;
using BasicDotnetTemplate.MainProject.Models.Settings; using BasicDotnetTemplate.MainProject.Models.Settings;
using BasicDotnetTemplate.MainProject.Services;
@@ -41,7 +42,6 @@ public static class ProgramUtils
return appSettings; return appSettings;
} }
public static OpenApiInfo CreateOpenApiInfo(AppSettings appSettings) public static OpenApiInfo CreateOpenApiInfo(AppSettings appSettings)
{ {
OpenApiInfo openApiInfo = new OpenApiInfo OpenApiInfo openApiInfo = new OpenApiInfo
@@ -83,11 +83,53 @@ public static class ProgramUtils
builder.Services.AddSwaggerGen(options => builder.Services.AddSwaggerGen(options =>
{ {
options.SwaggerDoc("v1", CreateOpenApiInfo(appSettings)); options.SwaggerDoc("v1", CreateOpenApiInfo(appSettings));
options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
Description = "Inserisci il Bearer Token nel formato **'Bearer {token}'**",
Name = "Authorization",
In = ParameterLocation.Header,
Type = SecuritySchemeType.Http,
Scheme = "Bearer"
});
options.AddSecurityDefinition("ApiKey", new OpenApiSecurityScheme
{
Description = "Inserisci la tua API Key nel campo appropriato.",
Name = "ApiKey",
In = ParameterLocation.Header,
Type = SecuritySchemeType.ApiKey
});
options.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "Bearer"
}
},
new string[] {}
},
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "ApiKey"
}
},
new string[] {}
}
});
}); });
Logger.Info("[ProgramUtils][AddOpenApi] Ended swagger doc"); Logger.Info("[ProgramUtils][AddOpenApi] Ended swagger doc");
} }
public static void AddServices(ref WebApplicationBuilder builder) public static void AddServices(ref WebApplicationBuilder builder)
{ {
Logger.Info("[ProgramUtils][AddServices] Adding services"); Logger.Info("[ProgramUtils][AddServices] Adding services");
@@ -99,7 +141,6 @@ public static class ProgramUtils
Logger.Info("[ProgramUtils][AddServices] Done services"); Logger.Info("[ProgramUtils][AddServices] Done services");
} }
public static void AddMiddlewares(ref WebApplication app) public static void AddMiddlewares(ref WebApplication app)
{ {
Logger.Info("[ProgramUtils][AddMiddlewares] Adding middlewares"); Logger.Info("[ProgramUtils][AddMiddlewares] Adding middlewares");
@@ -126,7 +167,6 @@ public static class ProgramUtils
Logger.Info("[ProgramUtils][AddMiddlewares] Done middlewares"); Logger.Info("[ProgramUtils][AddMiddlewares] Done middlewares");
} }
public static void AddDbContext(ref WebApplicationBuilder builder, AppSettings appSettings) public static void AddDbContext(ref WebApplicationBuilder builder, AppSettings appSettings)
{ {
Logger.Info("[ProgramUtils][AddDbContext] Adding DbContext"); Logger.Info("[ProgramUtils][AddDbContext] Adding DbContext");
@@ -168,10 +208,11 @@ public static class ProgramUtils
messages = String.IsNullOrEmpty(messages) ? "No context" : messages; messages = String.IsNullOrEmpty(messages) ? "No context" : messages;
Logger.Info($"[ProgramUtils][AddDbContext] {messages} added"); Logger.Info($"[ProgramUtils][AddDbContext] {messages} added");
} }
public static void AddScopes(ref WebApplicationBuilder builder) public static void AddScopes(ref WebApplicationBuilder builder)
{ {
Logger.Info("[ProgramUtils][AddScopes] Adding scopes"); Logger.Info("[ProgramUtils][AddScopes] Adding scopes");
builder.Services.AddScoped<IAuthService, AuthService>();
builder.Services.AddScoped<IJwtService, JwtService>();
Logger.Info("[ProgramUtils][AddScopes] Done scopes"); Logger.Info("[ProgramUtils][AddScopes] Done scopes");
} }

View File

@@ -3,7 +3,7 @@
{ {
"Settings": { "Settings": {
"Name": "MainProject", "Name": "MainProject",
"Version": "v1.0", "Version": "v1",
"Description": "This template contains basic configuration for a .Net 8 backend" "Description": "This template contains basic configuration for a .Net 8 backend"
}, },
"DatabaseSettings": { "DatabaseSettings": {
@@ -27,6 +27,15 @@
"Default": "Information", "Default": "Information",
"Microsoft.AspNetCore": "Warning" "Microsoft.AspNetCore": "Warning"
} }
},
"JWTSettings": {
"ValidAudience": "http://localhost:4200",
"ValidIssuer": "http://localhost:5000",
"Secret": "JWTAuthenticationHIGHsecuredPasswordVVVp1OH7Xzyr",
"ExpiredAfterMinsOfInactivity": 15
},
"EncryptionSettings": {
"Salt": "S7VIidfXQf1tOQYX"
} }
} }
} }