Adds Options for JwtAuthentication (30min prod - 1day dev)
This commit is contained in:
@@ -1,9 +1,5 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using Google.Apis.Oauth2.v2.Data;
|
using Google.Apis.Oauth2.v2.Data;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Hutopy.Application.Common.Interfaces;
|
using Hutopy.Application.Common.Interfaces;
|
||||||
using Hutopy.Application.Common.Models;
|
using Hutopy.Application.Common.Models;
|
||||||
using Hutopy.Application.Users.Models;
|
using Hutopy.Application.Users.Models;
|
||||||
@@ -12,7 +8,7 @@ using Hutopy.Infrastructure.Utils;
|
|||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Identity;
|
using Microsoft.AspNetCore.Identity;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Options;
|
||||||
|
|
||||||
namespace Hutopy.Infrastructure.Identity;
|
namespace Hutopy.Infrastructure.Identity;
|
||||||
|
|
||||||
@@ -22,7 +18,7 @@ public class IdentityService(
|
|||||||
IUserClaimsPrincipalFactory<ApplicationUser> userClaimsPrincipalFactory,
|
IUserClaimsPrincipalFactory<ApplicationUser> userClaimsPrincipalFactory,
|
||||||
IAuthorizationService authorizationService,
|
IAuthorizationService authorizationService,
|
||||||
IHttpContextAccessor contextAccessor,
|
IHttpContextAccessor contextAccessor,
|
||||||
IConfiguration configuration
|
IOptionsSnapshot<JwtOptions> jwtOptions
|
||||||
)
|
)
|
||||||
: IIdentityService
|
: IIdentityService
|
||||||
{
|
{
|
||||||
@@ -424,13 +420,12 @@ public class IdentityService(
|
|||||||
var user = await GetUserByUserNameAsync(userName);
|
var user = await GetUserByUserNameAsync(userName);
|
||||||
|
|
||||||
if (user is null) throw new InvalidOperationException();
|
if (user is null) throw new InvalidOperationException();
|
||||||
|
|
||||||
var jwtSection = configuration.GetRequiredSection("Authentication:Jwt");
|
|
||||||
|
|
||||||
var token = JwtTokenHelper.GenerateJwtToken(
|
var token = JwtTokenHelper.GenerateJwtToken(
|
||||||
issuer: jwtSection["Issuer"] ?? "",
|
expiresIn: jwtOptions.Value.Lifetime,
|
||||||
audience: jwtSection["Audience"] ?? "",
|
issuer: jwtOptions.Value.Issuer,
|
||||||
key: jwtSection["Key"] ?? "",
|
audience: jwtOptions.Value.Audience,
|
||||||
|
key: jwtOptions.Value.Key,
|
||||||
userId: user.Id,
|
userId: user.Id,
|
||||||
email: user.Email,
|
email: user.Email,
|
||||||
firstname: user.FirstName,
|
firstname: user.FirstName,
|
||||||
|
|||||||
11
src/Infrastructure/Identity/JwtOptions.cs
Normal file
11
src/Infrastructure/Identity/JwtOptions.cs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
namespace Hutopy.Infrastructure.Identity;
|
||||||
|
|
||||||
|
public record JwtOptions
|
||||||
|
{
|
||||||
|
public const string SectionName = "Authentication:Jwt";
|
||||||
|
|
||||||
|
public required TimeSpan Lifetime { get; init; }
|
||||||
|
public required string Issuer { get; init; }
|
||||||
|
public required string Audience { get; init; }
|
||||||
|
public required string Key { get; init; }
|
||||||
|
}
|
||||||
@@ -1,6 +1,4 @@
|
|||||||
using System;
|
using System.IdentityModel.Tokens.Jwt;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IdentityModel.Tokens.Jwt;
|
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Microsoft.IdentityModel.Tokens;
|
using Microsoft.IdentityModel.Tokens;
|
||||||
@@ -10,6 +8,7 @@ namespace Hutopy.Infrastructure.Utils;
|
|||||||
public static class JwtTokenHelper
|
public static class JwtTokenHelper
|
||||||
{
|
{
|
||||||
public static string GenerateJwtToken(
|
public static string GenerateJwtToken(
|
||||||
|
TimeSpan expiresIn,
|
||||||
string issuer,
|
string issuer,
|
||||||
string audience,
|
string audience,
|
||||||
string key,
|
string key,
|
||||||
@@ -42,7 +41,7 @@ public static class JwtTokenHelper
|
|||||||
issuer: issuer,
|
issuer: issuer,
|
||||||
audience: audience,
|
audience: audience,
|
||||||
claims: claims,
|
claims: claims,
|
||||||
expires: DateTime.Now.AddMinutes(1440),
|
expires: DateTime.Now.Add(expiresIn),
|
||||||
signingCredentials: credentials);
|
signingCredentials: credentials);
|
||||||
|
|
||||||
return new JwtSecurityTokenHandler().WriteToken(token);
|
return new JwtSecurityTokenHandler().WriteToken(token);
|
||||||
|
|||||||
@@ -1,14 +1,20 @@
|
|||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
using Hutopy.Application.Common.Interfaces;
|
using Hutopy.Application.Common.Interfaces;
|
||||||
|
using Hutopy.Infrastructure.Identity;
|
||||||
using Hutopy.Infrastructure.Utils;
|
using Hutopy.Infrastructure.Utils;
|
||||||
using Microsoft.AspNetCore.Authentication;
|
using Microsoft.AspNetCore.Authentication;
|
||||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
namespace Hutopy.Web.Controllers;
|
namespace Hutopy.Web.Controllers;
|
||||||
|
|
||||||
public class GoogleController(IIdentityService identityService, IHttpClientFactory httpClientFactory, IConfiguration configuration) : Controller
|
public class GoogleController(
|
||||||
|
IIdentityService identityService,
|
||||||
|
IHttpClientFactory httpClientFactory,
|
||||||
|
IOptionsSnapshot<JwtOptions> jwtOptions)
|
||||||
|
: Controller
|
||||||
{
|
{
|
||||||
[HttpPost("/api/google/sign-in")]
|
[HttpPost("/api/google/sign-in")]
|
||||||
public async Task<IActionResult> SignIn([FromBody] GoogleSignInRequest request)
|
public async Task<IActionResult> SignIn([FromBody] GoogleSignInRequest request)
|
||||||
@@ -61,12 +67,11 @@ public class GoogleController(IIdentityService identityService, IHttpClientFacto
|
|||||||
CookieAuthenticationDefaults.AuthenticationScheme,
|
CookieAuthenticationDefaults.AuthenticationScheme,
|
||||||
new ClaimsPrincipal(claimsIdentity));
|
new ClaimsPrincipal(claimsIdentity));
|
||||||
|
|
||||||
var jwtSection = configuration.GetRequiredSection("Authentication:Jwt");
|
|
||||||
|
|
||||||
var token = JwtTokenHelper.GenerateJwtToken(
|
var token = JwtTokenHelper.GenerateJwtToken(
|
||||||
jwtSection["Issuer"] ?? throw new ArgumentNullException("The Jwt issuer is missing."),
|
jwtOptions.Value.Lifetime,
|
||||||
jwtSection["Audience"] ?? throw new ArgumentNullException("The Jwt audience is missing."),
|
jwtOptions.Value.Issuer,
|
||||||
jwtSection["Key"] ?? throw new ArgumentNullException("The Jwt key is missing."),
|
jwtOptions.Value.Audience,
|
||||||
|
jwtOptions.Value.Key,
|
||||||
user.Id,
|
user.Id,
|
||||||
user.Email,
|
user.Email,
|
||||||
user.FirstName,
|
user.FirstName,
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using FastEndpoints;
|
|||||||
using Hutopy.Application;
|
using Hutopy.Application;
|
||||||
using Hutopy.Infrastructure;
|
using Hutopy.Infrastructure;
|
||||||
using Hutopy.Infrastructure.Data;
|
using Hutopy.Infrastructure.Data;
|
||||||
|
using Hutopy.Infrastructure.Identity;
|
||||||
using Hutopy.Web;
|
using Hutopy.Web;
|
||||||
using Hutopy.Web.Contents.Data;
|
using Hutopy.Web.Contents.Data;
|
||||||
using Hutopy.Web.Messages.Data;
|
using Hutopy.Web.Messages.Data;
|
||||||
@@ -89,6 +90,8 @@ builder.Services.AddDbContext<ContentDbContext>((_, options) =>
|
|||||||
options.UseSqlServer(builder.Configuration.GetConnectionString("ContentStore"));
|
options.UseSqlServer(builder.Configuration.GetConnectionString("ContentStore"));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
builder.Services.Configure<JwtOptions>(builder.Configuration.GetRequiredSection(JwtOptions.SectionName));
|
||||||
|
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
|
|
||||||
app.UseForwardedHeaders(
|
app.UseForwardedHeaders(
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
},
|
},
|
||||||
"Authentication": {
|
"Authentication": {
|
||||||
"Jwt": {
|
"Jwt": {
|
||||||
|
"Lifetime": "1.00:00:00",
|
||||||
"Audience": "hutopy",
|
"Audience": "hutopy",
|
||||||
"Issuer": "https://auth.hutopy.com",
|
"Issuer": "https://auth.hutopy.com",
|
||||||
"Key": "b2df428b9929d3ace7c598bbf4e496b2f0b71ab3cd4f94540356cfc35b000000"
|
"Key": "b2df428b9929d3ace7c598bbf4e496b2f0b71ab3cd4f94540356cfc35b000000"
|
||||||
|
|||||||
@@ -6,5 +6,10 @@
|
|||||||
"Microsoft.Hosting.Lifetime": "Information"
|
"Microsoft.Hosting.Lifetime": "Information"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"AllowedHosts": "*"
|
"AllowedHosts": "*",
|
||||||
|
"Authentication": {
|
||||||
|
"Jwt": {
|
||||||
|
"Lifetime": "00:30:00"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user