示例#1
0
        public void UniqueOutput()
        {
            // Verify that we generate and use a unique IV for
            // every encryption run such that encrypting the same
            // data will return different results.  This is an
            // important security best practice.

            const int iterations = 1000;

            var decrypted   = "We hold these truths to be self-evident, that all men are created equal.";
            var encryptions = new HashSet <string>();

            using (var cipher = new AesCipher())
            {
                for (int i = 0; i < iterations; i++)
                {
                    var encrypted = cipher.EncryptToBase64(decrypted);

                    Assert.DoesNotContain(encrypted, encryptions);
                    Assert.Equal(decrypted, cipher.DecryptStringFrom(encrypted));

                    encryptions.Add(encrypted);
                }
            }
        }
示例#2
0
        public async Task BlazorAsync()
        {
            await SyncContext.Clear;

            var cookie    = HttpContext.Request.Cookies.Where(c => c.Key == Service.SessionCookieName).First();
            var sessionId = cipher.DecryptStringFrom(cookie.Value);
            var session   = NeonHelper.JsonDeserialize <Session>(await cache.GetAsync(sessionId));

            session.ConnectionId = HttpContext.Connection.Id;

            await cache.SetAsync(session.Id, NeonHelper.JsonSerializeToBytes(session));

            WebsocketMetrics.CurrentConnections.Inc();
            WebsocketMetrics.ConnectionsEstablished.Inc();
            blazorProxyService.CurrentConnections.Add(session.ConnectionId);

            LogDebug($"Fwd [{session.Id}] to [{session.UpstreamHost}].");

            var error = await forwarder.SendAsync(HttpContext, $"{config.Backend.Scheme}://{session.UpstreamHost}", httpClient, forwarderRequestConfig, transformer);

            LogDebug($"Session [{session.Id}] closed.");

            if (error != ForwarderError.None)
            {
                var errorFeature = HttpContext.GetForwarderErrorFeature();
                var exception    = errorFeature.Exception;

                if (exception.GetType() != typeof(TaskCanceledException) &&
                    exception.GetType() != typeof(OperationCanceledException))
                {
                    LogError("_blazor", exception);
                }
            }
        }
示例#3
0
        /// <summary>
        /// <para>
        /// Upserts the cache entry with an expiration time defined by <see cref="Cache.DurationSeconds"/>.
        /// After this period, it's no longer possible to reconnect a Blazor session back to the server,
        /// so we remove the entry from the cache.
        /// </para>
        /// </summary>
        /// <param name="context">The <see cref="HttpContext"/>.</param>
        /// <param name="cache">The Cache.</param>
        /// <param name="cipher">The AES Cipher used to encrypt/decrypt cookies.</param>
        /// <param name="cacheOptions">The Cache options.</param>
        /// <param name="logger">The <see cref="INeonLogger"/></param>
        /// <returns></returns>
        public async Task InvokeAsync(
            HttpContext context,
            Service service,
            IDistributedCache cache,
            AesCipher cipher,
            DistributedCacheEntryOptions cacheOptions,
            INeonLogger logger)
        {
            await SyncContext.Clear;

            await _next(context);

            if (service.CurrentConnections.Contains(context.Connection.Id))
            {
                var cookie    = context.Request.Cookies.Where(c => c.Key == Service.SessionCookieName).First();
                var sessionId = cipher.DecryptStringFrom(cookie.Value);
                var session   = NeonHelper.JsonDeserialize <Session>(await cache.GetAsync(sessionId));

                if (session.ConnectionId == context.Connection.Id)
                {
                    await cache.SetAsync(session.Id, NeonHelper.JsonSerializeToBytes(session), cacheOptions);

                    WebsocketMetrics.CurrentConnections.Dec();
                    service.CurrentConnections.Remove(context.Connection.Id);
                }
            }
        }
示例#4
0
        public void Encrypt_ToBase64()
        {
            // Encrypt a byte array:

            using (var cipher = new AesCipher())
            {
                var decrypted = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
                var encrypted = cipher.EncryptToBase64(decrypted);

                Assert.Equal(decrypted, cipher.DecryptBytesFrom(encrypted));
            }

            // Encrypt a string:

            using (var cipher = new AesCipher())
            {
                var decrypted = "1234567890";
                var encrypted = cipher.EncryptToBase64(decrypted);

                Assert.Equal(decrypted, cipher.DecryptStringFrom(encrypted));
            }
        }