/
BearerTokenBuilder.cs
128 lines (102 loc) · 3.86 KB
/
BearerTokenBuilder.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Security.Cryptography.X509Certificates;
using Microsoft.IdentityModel.Tokens;
namespace Asos.DotNetCore.Auth.Api.ComponentTests
{
public class BearerTokenBuilder
{
private X509Certificate2 _signingCertificate;
private string _issuer = "https://issuer.com";
private string _audience = "https://subject.com";
private TimeSpan _life = TimeSpan.FromHours(1);
private DateTime _notBefore = DateTime.UtcNow;
private readonly List<Claim> _claims = new();
private readonly JwtSecurityTokenHandler _securityTokenHandler = new();
public BearerTokenBuilder IssuedBy(string issuer)
{
if (string.IsNullOrEmpty(issuer))
{
throw new ArgumentException("Issued by cannot be null or empty", nameof(issuer));
}
_issuer = issuer;
return this;
}
public BearerTokenBuilder ForAudience(string audience)
{
if (string.IsNullOrEmpty(audience))
{
throw new ArgumentException("Audience cannot be null or empty", nameof(audience));
}
_audience = audience;
return this;
}
public BearerTokenBuilder ForSubject(string subject)
{
if (string.IsNullOrEmpty(subject))
{
throw new ArgumentException("Subject cannot be null or empty", nameof(subject));
}
if (_claims.FirstOrDefault(claim => claim.Type == "sub") == null)
{
_claims.Add(new Claim("sub", subject));
}
return this;
}
public BearerTokenBuilder WithSigningCertificate(X509Certificate2 certificate)
{
_signingCertificate = certificate ?? throw new ArgumentException("Certificate cannot be null or empty", nameof(certificate));
return this;
}
public BearerTokenBuilder WithClaim(string claimType, string value)
{
if (string.IsNullOrEmpty(claimType))
{
throw new ArgumentException("Claim type cannot be null or empty", nameof(claimType));
}
if (value == null)
{
value = string.Empty;
}
_claims.Add(new Claim(claimType, value));
return this;
}
public BearerTokenBuilder WithLifetime(TimeSpan life)
{
_life = life;
return this;
}
public BearerTokenBuilder NotBefore(DateTime notBefore)
{
_notBefore = notBefore;
return this;
}
public string BuildToken()
{
if (_signingCertificate == null)
{
throw new InvalidOperationException(
"You must specify an X509 certificate to use for signing the JWT Token");
}
var signingCredentials = new SigningCredentials(new X509SecurityKey(_signingCertificate), SecurityAlgorithms.RsaSha256);
var notBefore = _notBefore;
var expires = notBefore.Add(_life);
var identity = new ClaimsIdentity(_claims);
var securityTokenDescriptor = new SecurityTokenDescriptor
{
Audience = _audience,
Issuer = _issuer,
NotBefore = notBefore,
Expires = expires,
SigningCredentials = signingCredentials,
Subject = identity
};
var token = _securityTokenHandler.CreateToken(securityTokenDescriptor);
var encodedAccessToken = _securityTokenHandler.WriteToken(token);
return encodedAccessToken;
}
}
}