Skip to content

Commit a8abb7a

Browse files
authored
Merge pull request #25 from barzin144/feature/data-protection
Implemented authentication cookie
2 parents 483ccb7 + d91338f commit a8abb7a

13 files changed

+320
-230
lines changed

.env_SAMPLE

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
ConnectionStrings__MongoDb= "mongodb://USERNAME:PASSWORD@mongo:27017"
2+
Jwt__PrivateKey= "PRIVATE_KEY"
3+
Jwt__Issuer= "https://localhost:8001"
4+
Jwt__AccessTokenExpirationMinutes= 2
5+
Jwt__Audience= "http://localhost:5010"
6+
Jwt__DataProtectionApplicationName= "microidp"
7+
Jwt__DataProtectionKeysPath= "./DataProtectionKeys"
8+
Jwt__CookieName= "microidp"
9+
Jwt__DataProtectionPurpose= "JwtCookieEncryption"
10+
OAuth__GoogleCallbackURL= "https://localhost:8001/api/auth/google-callback"
11+
OAuth__GoogleClientId= "GOOGLE_CLIENT_ID"
12+
OAuth__GoogleClientSecret= "GOOGLE_CLIENT_SECRET"
13+
ASPNETCORE_URLS= "https://+;http://+"
14+
ASPNETCORE_Kestrel__Certificates__Default__Path= "/https/aspnetcore.pfx"
15+
ASPNETCORE_Kestrel__Certificates__Default__Password= "1234567890"
16+
Cors__Origins= "http://localhost:3000"
17+
DBName= "microIDP"

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,5 @@ msbuild.wrn
4646
aspnetcore.crt
4747
aspnetcore.key
4848
aspnetcore.pfx
49+
**/DataProtectionKeys/
50+
.env

Domain/Models/AuthCookie.cs

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
namespace Domain.Models;
2+
3+
public class AuthCookie
4+
{
5+
public string AccessToken { get; set; }
6+
public string RefreshToken { get; set; }
7+
}

Domain/Models/JwtOptions.cs

+5
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,10 @@ public class JwtOptions
99
public int RefreshTokenExpirationMinutes { set; get; }
1010
public bool AllowMultipleLoginsFromTheSameUser { set; get; }
1111
public bool AllowSignoutAllUserActiveClients { set; get; }
12+
public string DataProtectionApplicationName { get; set; }
13+
public string DataProtectionKeysPath { get; set; }
14+
public string DataProtectionPurpose { get; set; }
15+
public string CookieName { get; set; }
16+
1217
}
1318
}

IoCConfig/ConfigureServicesExtensions.cs

+35-12
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
using Microsoft.Extensions.Configuration;
55
using Microsoft.Extensions.DependencyInjection;
66
using Microsoft.OpenApi.Models;
7-
using System.Collections.Generic;
87
using DataAccess;
98
using MongoDB.Driver;
109
using Domain.Repositories;
@@ -14,6 +13,10 @@
1413
using System.Security.Cryptography;
1514
using System;
1615
using Microsoft.AspNetCore.Authentication.JwtBearer;
16+
using Microsoft.AspNetCore.DataProtection;
17+
using System.IO;
18+
using System.Threading.Tasks;
19+
using System.Text.Json;
1720

1821
namespace IoCConfig
1922
{
@@ -59,9 +62,40 @@ public static void AddCustomAuthentication(this IServiceCollection services, ICo
5962
ValidAudience = configuration["Jwt:Audience"],
6063
IssuerSigningKey = new RsaSecurityKey(rsa)
6164
};
65+
66+
options.Events = new JwtBearerEvents
67+
{
68+
OnMessageReceived = context =>
69+
{
70+
if (context.Request.Cookies.TryGetValue(configuration["Jwt:CookieName"], out var encryptedToken))
71+
{
72+
var dataProtector = context.HttpContext.RequestServices
73+
.GetRequiredService<IDataProtectionProvider>()
74+
.CreateProtector(configuration["Jwt:DataProtectionPurpose"]);
75+
76+
try
77+
{
78+
var authCookie = JsonSerializer.Deserialize<AuthCookie>(dataProtector.Unprotect(encryptedToken));
79+
context.Token = authCookie.AccessToken;
80+
}
81+
catch
82+
{
83+
context.Fail("Invalid or tampered token");
84+
}
85+
}
86+
87+
return Task.CompletedTask;
88+
}
89+
};
6290
});
6391
}
6492

93+
public static void AddCustomDataProtection(this IServiceCollection services, IConfiguration configuration)
94+
{
95+
services.AddDataProtection()
96+
.PersistKeysToFileSystem(new DirectoryInfo(configuration["Jwt:DataProtectionKeysPath"]))
97+
.SetApplicationName(configuration["Jwt:DataProtectionApplicationName"]);
98+
}
6599
public static void AddCustomServices(this IServiceCollection services)
66100
{
67101
services.AddScoped<IJwtTokenService, JwtTokenService>();
@@ -87,17 +121,6 @@ public static void AddCustomSwagger(this IServiceCollection services)
87121
Title = "Micro IDP API Document",
88122
Version = "v1"
89123
});
90-
91-
options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
92-
{
93-
Description = @"JWT Authorization header using the Bearer scheme.",
94-
Name = "Authorization",
95-
In = ParameterLocation.Header,
96-
Type = SecuritySchemeType.ApiKey,
97-
Scheme = "Bearer"
98-
});
99-
100-
options.AddSecurityRequirement(new OpenApiSecurityRequirement() { { new OpenApiSecurityScheme { Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" }, Scheme = "oauth2", Name = "Bearer", In = ParameterLocation.Header, }, new List<string>() } });
101124
});
102125
}
103126

0 commit comments

Comments
 (0)