/// <summary> /// It tries to resolve refresh token id from claim <see cref="BearerSignInManagerDefaults.SignInServiceRefreshTokenIdClaimType"/> /// and then look in the database. If a refresh token has been found, it will be returned. /// </summary> public static async Task <ServiceResult <BearerTokenType> > FindRefreshTokenAsync <BearerTokenType>(IBearerTokenStore <BearerTokenType> refreshTokenStore, ClaimsPrincipal principal, ILogger?logger = null) where BearerTokenType : class, IBearerTokenEntity { principal = principal ?? throw BearerSignInManagerThrowHelper.GetPrincipalNullException(nameof(principal)); var refreshTokenIdResult = FindRefreshTokenId(principal); if (!refreshTokenIdResult.Succeeded) { return(ServiceResult <BearerTokenType> .Failure(refreshTokenIdResult)); } try { // Then we need the entity that belongs to refresh token id. var refreshTokenEntity = await refreshTokenStore.FindAsync(refreshTokenIdResult.Content); return(ReferenceEquals(refreshTokenEntity, null) ? ServiceResult <BearerTokenType> .Failure("The refresh token has been redeemed.") .WithHttpStatusCode(HttpStatusCode.BadRequest) : ServiceResult <BearerTokenType> .Success(refreshTokenEntity) .WithHttpStatusCode(HttpStatusCode.OK)); } catch (Exception error) { const string errorMessage = "Search for refresh token failed."; logger?.LogError(error, errorMessage); return(errorMessage.ToJsonError() .ToServiceResult <BearerTokenType>() .WithHttpStatusCode(HttpStatusCode.InternalServerError)); } }
/// <summary> /// The access token does contain user user id, user name and user roles. /// </summary> protected virtual async Task <bool> TrySetContextAccessTokenAsync(BearerSignInManagerContext <UserType, BearerTokenType> context) { var user = context.User ?? throw BearerSignInManagerThrowHelper.GetContextArgumentException(nameof(context.User)); var accessTokenDescriptor = signInManagerOptions.CreateAccessTokenDescriptor(); // Used by authentication middleware. accessTokenDescriptor.Claims.Add(ClaimTypes.NameIdentifier, user.Id); accessTokenDescriptor.Claims.Add(ClaimTypes.Name, user.UserName); try { var roles = await userManager.GetRolesAsync(user); if (roles != null) { foreach (var role in roles) { accessTokenDescriptor.Claims.Add(ClaimTypes.Role, role); } } context.AccessToken = BearerSignInManagerTools.GenerateJwtToken(accessTokenDescriptor, signInManagerOptions.SetDefaultTimesOnTokenCreation); return(true); } catch (Exception error) { context.SetResult(errorDetailsProvider.LogCriticalThenBuildAppropiateError <object>(error, "The access token could not be created.") .WithHttpStatusCode(HttpStatusCode.InternalServerError)); } return(false); }
/// <inheritdoc/> public async Task <IServiceResult <SignInTokens> > CreateTokensAsync(ClaimsPrincipal principal) { principal = principal ?? throw BearerSignInManagerThrowHelper.GetPrincipalNullException(nameof(principal)); var context = new BearerSignInManagerContext <UserType, BearerTokenType>(principal); if (await TrySetContextUserAsync(context) && await TrySetContextSignInTokensAsync(context)) { var authenticationTokens = new SignInTokens(context.AccessToken !, context.RefreshToken !); return(ServiceResult <SignInTokens> .Success(authenticationTokens).WithHttpStatusCode(HttpStatusCode.OK)); } return(context.Result !.CopyButFailed <object, SignInTokens>()); }
public bool HasPrincipalRefreshToken(BearerSignInManagerContext <UserType, BearerTokenType> context) { var principal = context.Principal ?? throw BearerSignInManagerThrowHelper.GetContextArgumentException(nameof(BearerSignInManagerContext <UserType, BearerTokenType> .Principal)); var hasRefreshTokenId = Guid.TryParse(principal.FindFirstValue(BearerSignInManagerDefaults.SignInServiceRefreshTokenIdClaimType), out _); if (!hasRefreshTokenId) { context.SetResult() .ToFailure("The refresh token is not valid.") .WithHttpStatusCode(HttpStatusCode.Unauthorized); return(false); } return(true); }