JWTHandler.cs 3.43 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
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;

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
24
        public bool ValidToken(string token, string encryptionAlgorithm = "HS256")
25
        {
26
            string secretKey = _configuration.GetStringAndWait("coscine/global/jwtsecret");
27
28
29
30
31
32
33
34
35

            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
36
37
38
39
40
            tokenValidationParameters.IssuerSigningKey = securityKey;
            // TODO: Validate those two
            tokenValidationParameters.ValidateAudience = false;
            tokenValidationParameters.ValidateIssuer = false;

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

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

65
66
67
68
69
70
71
72
73
74
75
76
77
78
        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
79
            DateTime centuryBegin = new DateTime(1970, 1, 1);
Benedikt Heinrichs's avatar
Benedikt Heinrichs committed
80
            var exp = new TimeSpan(DateTime.Now.AddMinutes(30).Ticks - centuryBegin.Ticks).TotalSeconds;
Benedikt Heinrichs's avatar
Benedikt Heinrichs committed
81
82
            var now = new TimeSpan(DateTime.Now.Ticks - centuryBegin.Ticks).TotalSeconds;

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

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

            return _jwtSecurityTokenHandler.WriteToken(securityToken);
        }

95
96
    }
}