From f22f708a3b98dbee905786e076bb0d171316bae8 Mon Sep 17 00:00:00 2001 From: Syndamia Date: Fri, 18 Dec 2020 12:58:36 +0200 Subject: Made user JWT more secure by checking the validity of the attached information and the given user (id) --- src/DevHive.Services/Services/UserService.cs | 47 ++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'src/DevHive.Services/Services/UserService.cs') diff --git a/src/DevHive.Services/Services/UserService.cs b/src/DevHive.Services/Services/UserService.cs index d3c0d0d..b2d5aee 100644 --- a/src/DevHive.Services/Services/UserService.cs +++ b/src/DevHive.Services/Services/UserService.cs @@ -105,6 +105,42 @@ namespace DevHive.Services.Services throw new InvalidOperationException("Unable to delete user!"); } + /// + /// Checks wether the given token's UserName and Roles are the same as these of the user with the given id. + /// + public async Task ValidJWT(Guid id, string rawTokenData) + { + // There is authorization name in the beginning, i.e. "Bearer eyJh..." + var jwt = new JwtSecurityTokenHandler().ReadJwtToken(rawTokenData.Remove(0, 7)); + + User user = await this._userRepository.GetByIdAsync(id) + ?? throw new ArgumentException("User does not exist!"); + + /* Check username */ + string jwtUserName = this.GetClaimTypeValues("unique_name", jwt.Claims)[0]; + + if (jwtUserName != user.UserName) + return false; + + /* Check roles */ + List jwtRoleNames = this.GetClaimTypeValues("role", jwt.Claims); + + // Check if jwt contains all user roles (if it doesn't, jwt is either old or tampered with) + foreach(var role in user.Roles) + { + if (!jwtRoleNames.Contains(role.Name)) + return false; + + jwtRoleNames.Remove(role.Name); + } + + // Check if jwt contains only roles of user + if (jwtRoleNames.Count > 0) + return false; + + return true; + } + private string GeneratePasswordHash(string password) { return string.Join(string.Empty, SHA512.HashData(Encoding.ASCII.GetBytes(password))); @@ -137,5 +173,16 @@ namespace DevHive.Services.Services SecurityToken token = tokenHandler.CreateToken(tokenDescriptor); return tokenHandler.WriteToken(token); } + + private List GetClaimTypeValues(string type, IEnumerable claims) + { + List toReturn = new(); + + foreach(var claim in claims) + if (claim.Type == type) + toReturn.Add(claim.Value); + + return toReturn; + } } } -- cgit v1.2.3