diff options
| author | Danail Dimitrov <danaildimitrov321@gmail.com> | 2021-02-28 20:52:56 +0200 |
|---|---|---|
| committer | Danail Dimitrov <danaildimitrov321@gmail.com> | 2021-02-28 20:52:56 +0200 |
| commit | 8d604f9e353cf0b8b8302fc6fb71dd4408c937fe (patch) | |
| tree | 9471b70a01b459c08bf2c1528cb4aba76d781f97 /src/Common/DevHive.Common | |
| parent | d53d67776f0746cc6eb8973f7c55767fcf82df65 (diff) | |
| parent | 2a85613d6827f5a1d151b856739863fbe9782143 (diff) | |
| download | DevHive-8d604f9e353cf0b8b8302fc6fb71dd4408c937fe.tar DevHive-8d604f9e353cf0b8b8302fc6fb71dd4408c937fe.tar.gz DevHive-8d604f9e353cf0b8b8302fc6fb71dd4408c937fe.zip | |
merge with dev
Diffstat (limited to 'src/Common/DevHive.Common')
| -rw-r--r-- | src/Common/DevHive.Common/DevHive.Common.csproj | 11 | ||||
| -rw-r--r-- | src/Common/DevHive.Common/Jwt/Interfaces/IJwtService.cs | 28 | ||||
| -rw-r--r-- | src/Common/DevHive.Common/Jwt/JwtService.cs | 86 |
3 files changed, 125 insertions, 0 deletions
diff --git a/src/Common/DevHive.Common/DevHive.Common.csproj b/src/Common/DevHive.Common/DevHive.Common.csproj new file mode 100644 index 0000000..cd60d85 --- /dev/null +++ b/src/Common/DevHive.Common/DevHive.Common.csproj @@ -0,0 +1,11 @@ +<Project Sdk="Microsoft.NET.Sdk"> + <ItemGroup> + <ProjectReference Include="..\DevHive.Common.Models\DevHive.Common.Models.csproj"/> + </ItemGroup> + <PropertyGroup> + <TargetFramework>net5.0</TargetFramework> + </PropertyGroup> + <ItemGroup> + <PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.8.0"/> + </ItemGroup> +</Project> diff --git a/src/Common/DevHive.Common/Jwt/Interfaces/IJwtService.cs b/src/Common/DevHive.Common/Jwt/Interfaces/IJwtService.cs new file mode 100644 index 0000000..352a7d5 --- /dev/null +++ b/src/Common/DevHive.Common/Jwt/Interfaces/IJwtService.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; + +namespace DevHive.Common.Jwt.Interfaces +{ + public interface IJwtService + { + /// <summary> + /// The generation of a JWT, when a new user registers or log ins + /// Tokens have an expiration time of 7 days. + /// </summary> + /// <param name="userId">User's Guid</param> + /// <param name="username">Users's username</param> + /// <param name="roleNames">List of user's roles</param> + /// <returns>Return a new JWT, containing the user id, username and roles.</returns> + string GenerateJwtToken(Guid userId, string username, List<string> roleNames); + + /// <summary> + /// Checks whether the given user, gotten by the "id" property, + /// is the same user as the one in the token (unless the user in the token has the admin role) + /// and the roles in the token are the same as those in the user, gotten by the id in the token + /// </summary> + /// <param name="userId">Guid of the user being validated</param> + /// <param name="rawToken">The raw token coming from the request</param> + /// <returns>Bool result of is the user authenticated to do an action</returns> + bool ValidateToken(Guid userId, string rawToken); + } +} diff --git a/src/Common/DevHive.Common/Jwt/JwtService.cs b/src/Common/DevHive.Common/Jwt/JwtService.cs new file mode 100644 index 0000000..9f316da --- /dev/null +++ b/src/Common/DevHive.Common/Jwt/JwtService.cs @@ -0,0 +1,86 @@ +using System; +using System.Collections.Generic; +using System.IdentityModel.Tokens.Jwt; +using System.Linq; +using System.Security.Claims; +using System.Security.Principal; +using DevHive.Common.Jwt.Interfaces; +using Microsoft.IdentityModel.Tokens; + +namespace DevHive.Common.Jwt +{ + public class JwtService : IJwtService + { + private readonly string _validationIssuer; + private readonly string _audience; + private readonly byte[] _signingKey; + + public JwtService(byte[] signingKey, string validationIssuer, string audience) + { + this._signingKey = signingKey; + this._validationIssuer = validationIssuer; + this._audience = audience; + } + + public string GenerateJwtToken(Guid userId, string username, List<string> roleNames) + { + var securityKey = new SymmetricSecurityKey(this._signingKey); + var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256); + + HashSet<Claim> claims = new() + { + new Claim("ID", $"{userId}"), + new Claim("Username", username) + }; + + foreach (var roleName in roleNames) + claims.Add(new Claim(ClaimTypes.Role, roleName)); + + SecurityTokenDescriptor securityTokenDescriptor = new() + { + Issuer = this._validationIssuer, + Audience = this._audience, + Subject = new ClaimsIdentity(claims), + Expires = DateTime.Today.AddDays(7), + SigningCredentials = credentials, + }; + + JwtSecurityTokenHandler tokenHandler = new(); + SecurityToken token = tokenHandler.CreateToken(securityTokenDescriptor); + + return tokenHandler.WriteToken(token); + } + + public bool ValidateToken(Guid userId, string rawToken) + { + var tokenHandler = new JwtSecurityTokenHandler(); + var validationParameters = GetValidationParameters(); + string actualToken = rawToken.Remove(0, 7); + + IPrincipal principal = tokenHandler.ValidateToken(actualToken, validationParameters, out SecurityToken validatedToken); + JwtSecurityToken jwtToken = tokenHandler.ReadJwtToken(actualToken); + + if (!principal.Identity.IsAuthenticated) + return false; + else if (principal.IsInRole("Admin")) + return true; + else if (jwtToken.Claims.FirstOrDefault(x => x.Type == "ID").Value != userId.ToString()) + return false; + else + return true; + } + + private TokenValidationParameters GetValidationParameters() + { + return new TokenValidationParameters() + { + ValidateLifetime = true, + ValidateAudience = true, + ValidateIssuer = true, + ValidIssuer = this._validationIssuer, + ValidAudience = this._audience, + IssuerSigningKey = new SymmetricSecurityKey(this._signingKey) + }; + } + } +} |
