Exemple #1
0
        /// <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);
        }