hello-shop/src/HelloShop.IdentityService/Authentication/CustomJwtBearerHandler.cs

61 lines
2.5 KiB
C#

// Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information.
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.BearerToken;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using System.Text.Encodings.Web;
namespace HelloShop.IdentityService.Authentication;
public class CustomJwtBearerHandler(IOptionsMonitor<CustomJwtBearerOptions> options, ILoggerFactory logger, UrlEncoder encoder, TimeProvider timeProvider) : SignInAuthenticationHandler<CustomJwtBearerOptions>(options, logger, encoder)
{
protected override Task<AuthenticateResult> HandleAuthenticateAsync() => throw new NotImplementedException();
protected override async Task HandleSignInAsync(ClaimsPrincipal user, AuthenticationProperties? properties)
{
var utcNow = timeProvider.GetUtcNow();
JwtSecurityTokenHandler tokenHandler = new();
var signingKey = new SymmetricSecurityKey(Encoding.Default.GetBytes(Options.IssuerSigningKey));
var accessTokenDescriptor = new SecurityTokenDescriptor
{
Issuer = Options.Issuer,
Audience = Options.Audience,
Subject = user.Identity as ClaimsIdentity,
SigningCredentials = new(signingKey, Options.SecurityAlgorithm),
Expires = utcNow.Add(Options.AccessTokenExpiration).LocalDateTime,
};
var accessToken = tokenHandler.CreateJwtSecurityToken(accessTokenDescriptor);
var refreshTokenDescriptor = new SecurityTokenDescriptor
{
Issuer = Options.Issuer,
Audience = Options.Audience,
Subject = user.Identity as ClaimsIdentity,
SigningCredentials = new(signingKey, Options.SecurityAlgorithm),
Expires = utcNow.Add(Options.RefreshTokenExpiration).LocalDateTime,
};
var refreshToken = tokenHandler.CreateJwtSecurityToken(refreshTokenDescriptor);
AccessTokenResponse response = new()
{
AccessToken = tokenHandler.WriteToken(accessToken),
ExpiresIn = (long)Options.AccessTokenExpiration.TotalSeconds,
RefreshToken = tokenHandler.WriteToken(refreshToken)
};
await Context.Response.WriteAsJsonAsync(response);
}
protected override Task HandleSignOutAsync(AuthenticationProperties? properties) => throw new NotImplementedException();
}