JWTHandler.cs 3.46 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
using Coscine.Api.Project.Exceptions;
using Coscine.Configuration;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;

namespace Coscine.Api.Project
{
    public class JWTHandler
    {
        private readonly IConfiguration _configuration;
        private readonly JwtSecurityTokenHandler _jwtSecurityTokenHandler;

        public JWTHandler(IConfiguration configuration)
        {
            _configuration = configuration;
            _jwtSecurityTokenHandler = new JwtSecurityTokenHandler();
        }

Benedikt Heinrichs's avatar
Benedikt Heinrichs committed
25
        public bool ValidToken(string token, string encryptionAlgorithm = "HS256")
26
        {
27
            string secretKey = _configuration.GetStringAndWait("coscine/global/jwtsecret");
28
29
30
31
32
33
34
35
36

            if (secretKey == null)
            {
                throw new ArgumentNullException("JWT Secret Configuration value is not set!");
            }

            var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secretKey));

            TokenValidationParameters tokenValidationParameters = new TokenValidationParameters();
Benedikt Heinrichs's avatar
Benedikt Heinrichs committed
37
38
39
40
41
            tokenValidationParameters.IssuerSigningKey = securityKey;
            // TODO: Validate those two
            tokenValidationParameters.ValidateAudience = false;
            tokenValidationParameters.ValidateIssuer = false;

42
43
44
45
            try
            {
                _jwtSecurityTokenHandler.ValidateToken(token, tokenValidationParameters, out SecurityToken securityToken);
            }
Benedikt Heinrichs's avatar
Benedikt Heinrichs committed
46
            catch (Exception)
47
48
49
50
51
52
            {
                return false;
            }
            return true;
        }

Benedikt Heinrichs's avatar
Benedikt Heinrichs committed
53
        public IEnumerable<Claim> GetContents(string jwt, string encryptionAlgorithm = "HS256")
54
        {
Benedikt Heinrichs's avatar
Benedikt Heinrichs committed
55
            if (ValidToken(jwt, encryptionAlgorithm))
56
57
58
59
60
61
62
63
64
65
            {
                var token = _jwtSecurityTokenHandler.ReadJwtToken(jwt);
                return token.Claims;
            }
            else
            {
                throw new InvalidTokenException("Invalid token!");
            }
        }

66
67
68
69
70
71
72
73
74
75
76
77
78
79
        public string GenerateJwtToken(IReadOnlyDictionary<string, string> payloadContents, string encryptionAlgorithm = "HS256")
        {
            string secretKey = _configuration.GetStringAndWait("coscine/global/jwtsecret");

            if (secretKey == null)
            {
                throw new ArgumentNullException("JWT Secret Configuration value is not set!");
            }

            var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secretKey));
            var signingCredentials = new SigningCredentials(securityKey, encryptionAlgorithm);

            var payloadClaims = payloadContents.Select(c => new Claim(c.Key, c.Value));

Benedikt Heinrichs's avatar
Benedikt Heinrichs committed
80
81
82
83
            DateTime centuryBegin = new DateTime(1970, 1, 1);
            var exp = new TimeSpan(DateTime.Now.AddYears(1).Ticks - centuryBegin.Ticks).TotalSeconds;
            var now = new TimeSpan(DateTime.Now.Ticks - centuryBegin.Ticks).TotalSeconds;

84
            var payload = new JwtPayload(payloadClaims);
Benedikt Heinrichs's avatar
Benedikt Heinrichs committed
85
86
87
88
89
            payload.Add("iss", "coscine");
            payload.Add("aud", "coscine");
            payload.Add("iat", (long) now);
            payload.Add("exp", (long) exp);

90
91
92
93
94
95
            var header = new JwtHeader(signingCredentials);
            var securityToken = new JwtSecurityToken(header, payload);

            return _jwtSecurityTokenHandler.WriteToken(securityToken);
        }

96
97
    }
}