Example #1
0
        /// <summary>
        /// Private and generic tokenrequest. The function overloads has been split iot keep one generic token exchange method.
        /// </summary>
        /// <param name="request">TokenRequest</param>
        /// <param name="grantType">Specified method of login.</param>
        /// <returns>A valid json web token.</returns>
        public async Task <TokenResult> TokenExchange(TokenRequest request, GrantType grantType)
        {
            User user = null;

            switch (grantType)
            {
            case GrantType.Tenant:
                if (string.IsNullOrWhiteSpace(request.TenantKey))
                {
                    return(new TokenResult(400, "This tenantkey is unkown."));
                }

                user = (await _userService.FindByTenantKeyAsync(request.TenantKey))?.Entity;
                if (user == null)
                {
                    return(new TokenResult(400, "This tenantkey is unkown."));
                }
                break;

            case GrantType.Password:

                if (string.IsNullOrEmpty(request.Email) || string.IsNullOrEmpty(request.Password))
                {
                    return(new TokenResult(400, "The username and/or password are required."));
                }

                // be sure to check that the username is the email address // or rewrite the service functionality to also find by username
                user = await _userManager.FindByEmailAsync(_cryptoProvider.EncryptPrivate(request.Email));

                if (user == null)
                {
                    user = await _userManager.FindByNameAsync(request.Email);

                    if (user == null)
                    {
                        return(new TokenResult(400, "The username/password couple is invalid."));
                    }
                }

                if (!await _userManager.CheckPasswordAsync(user, request.Password))
                {
                    return(new TokenResult(400, "The username/password couple is invalid."));
                }

                break;
            }

            // when no user is found, then terminate the request.
            if (user == null)
            {
                return(new TokenResult(400, "The specified grant type is not supported."));
            }

            if (!await _userManager.IsEmailConfirmedAsync(user))
            {
                return(new TokenResult(401, "Please confirm your email or reset your password."));
            }

            if (user.BlockedUntilUtc.HasValue && user.BlockedUntilUtc.Value > DateTime.UtcNow)
            {
                return(new TokenResult(401, MessageHelper.BlockedUntilMessage(user.BlockedUntilUtc)));
            }

            if (await _userManager.IsLockedOutAsync(user))
            {
                return(new TokenResult(401, "The account is locked out."));
            }

            if (!await _signInManager.CanSignInAsync(user))
            {
                return(new TokenResult(401, "The specified user is not allowed to sign in."));
            }

            // reset locks
            await _userManager.ResetAccessFailedCountAsync(user);

            await _userManager.SetLockoutEnabledAsync(user, false);

            // Create a new authentication token.
            var token = await GetJwtSecurityToken(user, grantType);

            return(new TokenResult(200)
            {
                TokenData = new TokenData
                {
                    Token = new JwtSecurityTokenHandler().WriteToken(token),
                    ExpiredDateUtc = token.ValidTo
                }
            });
        }