From 13ed90803cbe67838cec7f92fbad0be4646c2ab7 Mon Sep 17 00:00:00 2001 From: Astrian Zheng Date: Fri, 15 Sep 2023 16:05:38 +1000 Subject: [PATCH] JWT Verify --- .../Controllers/HomeController.cs | 87 +++++++++++++++++++ FIT5032-Assignment/FIT5032-Assignment.csproj | 22 ++++- FIT5032-Assignment/Web.config | 12 +++ FIT5032-Assignment/packages.config | 8 +- 4 files changed, 126 insertions(+), 3 deletions(-) diff --git a/FIT5032-Assignment/Controllers/HomeController.cs b/FIT5032-Assignment/Controllers/HomeController.cs index 0ec1de8..8dc7deb 100644 --- a/FIT5032-Assignment/Controllers/HomeController.cs +++ b/FIT5032-Assignment/Controllers/HomeController.cs @@ -10,11 +10,87 @@ using System.Text; using BCryptNet = BCrypt.Net.BCrypt; using System.Diagnostics; using System.Net; +using System.IdentityModel.Tokens.Jwt; +using Microsoft.IdentityModel.Tokens; +using System.IO; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.OpenSsl; +using Org.BouncyCastle.Security; namespace FIT5032_Assignment.Controllers { public class HomeController : Controller { + public static RsaSecurityKey LoadRsaSecurityKeyFromPem(string pem) + { + TextReader textReader = new StringReader(pem); + PemReader pemReader = new PemReader(textReader); + AsymmetricKeyParameter keyParameter = (AsymmetricKeyParameter)pemReader.ReadObject(); + + RSAParameters rsaParameters = DotNetUtilities.ToRSAParameters((Org.BouncyCastle.Crypto.Parameters.RsaKeyParameters)keyParameter); + RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); + rsa.ImportParameters(rsaParameters); + + return new RsaSecurityKey(rsa); + } + private String loginVerify(string token) + { + + var jwtHandler = new JwtSecurityTokenHandler(); + var jwtToken = jwtHandler.ReadJwtToken(token); + + string base64Publickey = "LS0tLS1CRUdJTiBSU0EgUFVCTElDIEtFWS0tLS0tCk1JSUJDZ0tDQVFFQTRUWEQwVEh4NnJjNXlQcXM0Skw5M01nVEgvTS95Z2s3V1pYWWsrS01XTTA0bDdzM3owRlMKODlDRE56SFJkbVpJb3RCbDgrcUJ5TUwvck5VcUhXMnJ1Uzg0dmxFaWdza2djK2RsaitCZXFsaGsySFRpQitpegpQcGdCU1FJc2YrZjdSU3dkYktFS2hRQm1La3MxVGF4YWNDUndPVWJKT1VQbjJXZmhVSHhRd0FwZGNCQWdNdHVNCld3QzJZRThGblFRZDhxc3dMTTBGQWhoSzUrdXRXY0s0bHdCVlFxUGJRaUJZYnZmWXkwYVF6UFB2V2NMR1JvR00KUVA1b1JCTmRuRzQ4Sm9Eb2tCSEJkbCt4RzM1L1U2N1BvejFKY0VVSnpWTHdIUFNHa0xyRU1OYlFrbnJSK2tHZwpnS1dWNFpvYWVOSHZVeFE3YVg3SElFMlc1UnIwRmxGUG1RSURBUUFCCi0tLS0tRU5EIFJTQSBQVUJMSUMgS0VZLS0tLS0K"; + RsaSecurityKey rsaKey = LoadRsaSecurityKeyFromPem(Encoding.UTF8.GetString(Convert.FromBase64String(base64Publickey))); + // Valid time 3600s + var validationParameters = new TokenValidationParameters() + { + ValidIssuer = "https://auth.passage.id/v1/apps/ZHM5whW5xsZEczTn2loffzjN", + ValidateAudience = false, + IssuerSigningKey = rsaKey, + ValidateLifetime = true, + ClockSkew = TimeSpan.FromSeconds(3600) + }; + + try + { + var claimsPrincipal = jwtHandler.ValidateToken(token, validationParameters, out var rawValidatedToken); + } + catch (SecurityTokenExpiredException) + { + Trace.WriteLine("Token has expired"); + return null; + } + catch (SecurityTokenInvalidSignatureException) + { + Trace.WriteLine("Token has invalid signature"); + return null; + } + catch (SecurityTokenInvalidIssuerException) + { + Trace.WriteLine("Token has invalid issuer"); + return null; + } + catch (SecurityTokenInvalidAudienceException) + { + Trace.WriteLine("Token has invalid audience"); + return null; + } + catch (SecurityTokenValidationException) + { + Trace.WriteLine("Token failed validation"); + return null; + } + catch (ArgumentException) + { + Trace.WriteLine("Token was empty or null"); + return null; + } + + string sub = jwtToken.Claims.First(claim => claim.Type == "sub").Value; + + return sub; + } + private Database1Entities db = new Database1Entities(); private string GenerateRandomString(int length) @@ -41,6 +117,17 @@ namespace FIT5032_Assignment.Controllers // See cookies var psg_auth_token = Request.Cookies["psg_auth_token"]; Trace.WriteLine(psg_auth_token.Value); + // JWT Verify + string sub = loginVerify(psg_auth_token.Value); + if (sub == null) + { + return RedirectToAction("Login"); + } + else + { + Trace.WriteLine(sub); + } + return View(); } diff --git a/FIT5032-Assignment/FIT5032-Assignment.csproj b/FIT5032-Assignment/FIT5032-Assignment.csproj index cafcde5..8c6e050 100644 --- a/FIT5032-Assignment/FIT5032-Assignment.csproj +++ b/FIT5032-Assignment/FIT5032-Assignment.csproj @@ -49,6 +49,9 @@ ..\packages\BCrypt.Net-Next.4.0.3\lib\net48\BCrypt.Net-Next.dll + + ..\packages\BouncyCastle.1.8.9\lib\BouncyCastle.Crypto.dll + ..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.dll @@ -62,6 +65,18 @@ ..\packages\Microsoft.Bcl.AsyncInterfaces.6.0.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll + + ..\packages\Microsoft.IdentityModel.Abstractions.7.0.0\lib\net472\Microsoft.IdentityModel.Abstractions.dll + + + ..\packages\Microsoft.IdentityModel.JsonWebTokens.7.0.0\lib\net472\Microsoft.IdentityModel.JsonWebTokens.dll + + + ..\packages\Microsoft.IdentityModel.Logging.7.0.0\lib\net472\Microsoft.IdentityModel.Logging.dll + + + ..\packages\Microsoft.IdentityModel.Tokens.7.0.0\lib\net472\Microsoft.IdentityModel.Tokens.dll + ..\packages\Newtonsoft.Json.13.0.2\lib\net45\Newtonsoft.Json.dll @@ -71,8 +86,11 @@ - - ..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll + + ..\packages\System.IdentityModel.Tokens.Jwt.7.0.0\lib\net472\System.IdentityModel.Tokens.Jwt.dll + + + ..\packages\System.Memory.4.5.5\lib\net461\System.Memory.dll diff --git a/FIT5032-Assignment/Web.config b/FIT5032-Assignment/Web.config index 3e0f377..6bf3907 100644 --- a/FIT5032-Assignment/Web.config +++ b/FIT5032-Assignment/Web.config @@ -56,6 +56,18 @@ + + + + + + + + + + + + diff --git a/FIT5032-Assignment/packages.config b/FIT5032-Assignment/packages.config index e950260..b586359 100644 --- a/FIT5032-Assignment/packages.config +++ b/FIT5032-Assignment/packages.config @@ -3,6 +3,7 @@ + @@ -13,12 +14,17 @@ + + + + - + +