61 lines
2.5 KiB
C#
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();
|
|
}
|