68 lines
3.2 KiB
C#
68 lines
3.2 KiB
C#
using AutoMapper;
|
|
using DigitalData.Core.Abstractions.Security;
|
|
using DigitalData.Core.Security.Config;
|
|
using Microsoft.Extensions.Options;
|
|
using Microsoft.IdentityModel.Tokens;
|
|
using System.IdentityModel.Tokens.Jwt;
|
|
|
|
namespace DigitalData.Core.Security
|
|
{
|
|
public class JwtSignatureHandler<TPrincipal> : JwtSecurityTokenHandler, IJwtSignatureHandler<TPrincipal>
|
|
{
|
|
private readonly ClaimDescriptor<TPrincipal> _claimDescriptor;
|
|
|
|
private readonly IMapper _mapper;
|
|
|
|
private readonly TokenParams _params;
|
|
|
|
private readonly ICryptograph _cryptograph;
|
|
|
|
public JwtSignatureHandler(IOptions<ClaimDescriptor<TPrincipal>> claimDescriptorOptions, IMapper mapper, IOptions<TokenParams> tokenParamOptions, ICryptograph cryptograph)
|
|
{
|
|
_claimDescriptor = claimDescriptorOptions.Value;
|
|
_mapper = mapper;
|
|
_params = tokenParamOptions.Value;
|
|
_cryptograph = cryptograph;
|
|
}
|
|
|
|
public SecurityToken CreateToken(TPrincipal subject, TokenDescription description)
|
|
{
|
|
var descriptor = _mapper.Map(description);
|
|
descriptor.Claims = _claimDescriptor.CreateClaims?.Invoke(subject);
|
|
descriptor.Subject = _claimDescriptor.CreateSubject?.Invoke(subject);
|
|
return CreateToken(descriptor);
|
|
}
|
|
|
|
public SecurityToken CreateToken(TPrincipal subject, string issuer, string audience)
|
|
{
|
|
var description = _params.Descriptions?.Get(issuer: issuer, audience: audience)
|
|
?? throw new InvalidOperationException($"No or multiple token description found for issuer '{issuer}' and audience '{audience}'.");
|
|
|
|
description.SigningCredentials = _cryptograph.PrivateKeys
|
|
.Get(issuer: issuer, audience: audience)
|
|
.CreateSigningCredentials(algorithm: description.SigningAlgorithm, digest: description.SigningDigest);
|
|
|
|
return CreateToken(subject: subject, description: description);
|
|
}
|
|
|
|
public SecurityToken CreateToken(TPrincipal subject, string apiRoute)
|
|
{
|
|
var description = _params.Descriptions.SingleOrDefault(description => description.ApiRoute == apiRoute)
|
|
?? throw new InvalidOperationException($"No or multiple token description found for api route '{apiRoute}'.");
|
|
|
|
description.SigningCredentials = _cryptograph.PrivateKeys
|
|
.Get(issuer: description.Issuer, audience: description.Audience)
|
|
.CreateSigningCredentials(algorithm: description.SigningAlgorithm, digest: description.SigningDigest);
|
|
|
|
return CreateToken(subject: subject, description: description);
|
|
}
|
|
|
|
public string WriteToken(SecurityTokenDescriptor descriptor) => WriteToken(CreateToken(descriptor));
|
|
|
|
public string WriteToken(TPrincipal subject, TokenDescription description) => WriteToken(CreateToken(subject: subject, description: description));
|
|
|
|
public string WriteToken(TPrincipal subject, string issuer, string audience) => WriteToken(CreateToken(subject: subject, issuer: issuer, audience: audience));
|
|
|
|
public string WriteToken(TPrincipal subject, string apiRoute) => WriteToken(CreateToken(subject: subject, apiRoute: apiRoute));
|
|
}
|
|
} |