예제 #1
0
        public void CryptoRandomizer_BasicUsage()
        {
            CryptoRandomizer randomizer = new CryptoRandomizer();
            int blockSize  = 20000;
            int iterations = 50000;

            for (int i = 0; i < iterations; i++)
            {
                // Get some random bytes
                byte[] bytes = new byte[blockSize];
                randomizer.GetBytes(bytes);
                Assert.IsTrue(bytes.Length == blockSize);

                // Get Random Int
                int randomInt = randomizer.Next();
                // Not really testible

                // Get Random Int less than 5
                int randomIntLess5 = randomizer.Next(5);
                Assert.IsTrue(randomIntLess5 < 5);

                // Get Random Int between 1000 - 2000
                int randomIntBetween1000And1500 = randomizer.Next(1000, 2000);
                Assert.IsTrue(randomIntBetween1000And1500 > 999 && randomIntBetween1000And1500 < 20001);

                double randomDouble = randomizer.NextDouble();
                // Not really testible
            }
        }
예제 #2
0
        private async Task <TokenAndClaimsPrincipal> CreateShortTokenAsync(
            User user, string lat2r, string lat2, long sessionId)
        {
            List <Claim> claims = new List <Claim>
            {
                new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
                new Claim(TokenClaimNames.LongToken2Ran, lat2r),
                new Claim(JwtRegisteredClaimNames.Jti,
                          CryptoRandomizer.GetRandomString(DbColumnSizes.BlackListShortToken_TokenId))
            };

            var roleNames = await userManager.GetRolesAsync(user);

            foreach (var role in roleNames)
            {
                claims.Add(new Claim(ClaimTypes.Role, role));
            }

            var expiration = DateTime.UtcNow.AddMinutes(jwtOptions.ShortTokenLiveTimeMinutes);

            var token = new JwtSecurityToken(
                claims: claims.ToArray(),
                expires: expiration);

            var claimsIdentity  = new ClaimsIdentity(claims, "JwtShortToken");
            var claimsPrincipal = new ClaimsPrincipal(claimsIdentity);

            return(new TokenAndClaimsPrincipal
            {
                ClaimsPrincipal = new SunClaimsPrincipal(claimsPrincipal, rolesCache, sessionId, lat2),
                Token = cryptService.Crypt(CipherSecrets.ShortJwt, token.Payload.SerializeToJson()),
                Expiration = expiration
            });
        }
예제 #3
0
        private string CreateLong2AuthToken(LongSession longSession, out string lat2r)
        {
            var key = new SymmetricSecurityKey(
                Encoding.UTF8.GetBytes(jwtOptions.LongJwtSecurityKey));
            var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256Signature);

            lat2r = CryptoRandomizer.GetRandomString(10);

            List <Claim> claims = new List <Claim>
            {
                new Claim(ClaimTypes.NameIdentifier, longSession.UserId.ToString()),
                new Claim(TokenClaimNames.LongToken2Ran, lat2r),
                new Claim(TokenClaimNames.LongToken2Db, longSession.LongToken2),
                new Claim(TokenClaimNames.SessionId, longSession.Id.ToString())
            };

            var token = new JwtSecurityToken(
                issuer: jwtOptions.Issuer,
                audience: jwtOptions.Issuer,
                claims: claims.ToArray(),
                expires: longSession.ExpirationDate,
                signingCredentials: credentials);

            return(new JwtSecurityTokenHandler().WriteToken(token));
        }
        private string GetRandomDirName(List <DirectoryInfo> directories)
        {
            CryptoRandomizer randomizer = new CryptoRandomizer();
            int index = randomizer.Next(0, directories.Count);

            return(directories[index].FullName);
        }
예제 #5
0
        public void SymmetricEncryptor_HeavyUsage()
        {
            CryptoRandomizer random         = new CryptoRandomizer();
            const int        Iterations     = 100;
            const int        MaxMemoryBlock = 100000;


            for (int i = 0; i < Iterations; i++)
            {
                int    blockSize = random.Next(MaxMemoryBlock);
                byte[] buffer    = new ByteGenerator().GenerateBytes(blockSize);
                string key       = CryptoString.GenerateRandomText(1000);

                byte[] decryptedBuffer;
                byte[] encryptedBuffer;

                using (SymmetricEncryptor encryptor = new SymmetricEncryptor())
                {
                    //Encrypt
                    encryptedBuffer = encryptor.EncryptBytes(buffer, key);

                    // Decrypt
                    decryptedBuffer = encryptor.DecryptBytes(encryptedBuffer, key);
                }                 // IDispose - Closes and clears the keys in memory

                // Assert - Check to make sure the bytes are all the same
                Assert.IsTrue(buffer.SequenceEqual(decryptedBuffer));
            }
        }
예제 #6
0
        public async Task <SunClaimsPrincipal> RenewSecurityTokensAsync(HttpResponse response, User user,
                                                                        LongSession longSession = null)
        {
            void GenerateTokens(LongSession longSession1)
            {
                longSession1.LongToken1     = CryptoRandomizer.GetRandomString(LongSession.LongToken1Length);
                longSession1.LongToken2     = CryptoRandomizer.GetRandomString(LongSession.LongToken2Length);
                longSession1.ExpirationDate = DateTime.UtcNow.AddDays(jwtOptions.LongTokenLiveTimeDays);
            }

            if (longSession == null)
            {
                longSession = new LongSession
                {
                    UserId     = user.Id,
                    DeviceInfo = ""
                };

                GenerateTokens(longSession);

                longSession.Id = await db.InsertWithInt64IdentityAsync(longSession);
            }
            else
            {
                GenerateTokens(longSession);
                await db.UpdateAsync(longSession);
            }


            var lat2Token = CreateLong2AuthToken(longSession, out string lat2r);

            response.Cookies.Append(
                TokenClaimNames.LongToken2CoockiName,
                lat2Token,
                new CookieOptions
            {
                Path        = "/",
                HttpOnly    = true,
                IsEssential = true,
                Expires     = longSession.ExpirationDate
            }
                );

            TokenAndClaimsPrincipal tokenAndClaimsPrincipal =
                await GenerateShortAuthTokenAsync(user, lat2r, longSession.LongToken2, longSession.Id);

            string json = JsonConvert.SerializeObject(new
            {
                LongToken = new
                {
                    Token      = longSession.LongToken1,
                    Expiration = longSession.ExpirationDate.ToInvariantString()
                },
                ShortToken = tokenAndClaimsPrincipal.Token
            }, jsonSerializerSettings);

            response.Headers.Add(Headers.TokensHeaderName, json);

            return(tokenAndClaimsPrincipal.ClaimsPrincipal);
        }
예제 #7
0
        public string MakeCaptchaToken()
        {
            var token  = CryptoRandomizer.GetRandomString(64);
            var answer = GenerateCaptchaText();

            captchaCacheService.Cache(token, answer);
            return(token);
        }
예제 #8
0
        public FileAndDir GetNewImageNameAndDir(string ext)
        {
            var cid = CryptoRandomizer.GetRandomString(
                DbColumnSizes.FileNameWithDirSize -
                8); // Why -8. 4 needed for directory start "123/", and 4 needed for extension ".jpg"

            byte[] bites = Encoding.UTF8.GetBytes(cid);

            return(new FileAndDir(cid + ext, bites[0].ToString()));
        }
예제 #9
0
        public void Crypt()
        {
            string dataToCrypt = CryptoRandomizer.GenerateSecurityKey(16).ToUrlSafeBase64();

            rsaCypherMock = new Mock <IRsaCypher>();

            rsaCypherMock.Setup(x => x.GenerateKeys()).Returns <(string, string)>(result => result);
            var keys = rsaCypherMock.Object.GenerateKeys();

            string cryptedText   = rsaCypherMock.Object.Crypt(keys.publicKey, dataToCrypt);
            string decryptedText = rsaCypherMock.Object.Decrypt(keys.privateKey, cryptedText);

            Assert.Equal(decryptedText, dataToCrypt);
        }
예제 #10
0
        public async Task <string> GenereteEmailToken(User user)
        {
            var claims = new List <Claim>
            {
                new Claim(ClaimTypes.NameIdentifier, user.Id),
                new Claim(JwtRegisteredClaimNames.Email, user.Email),
                new Claim(JwtRegisteredClaimNames.Jti, CryptoRandomizer.GetRandomString(16)),
            };

            var token = new JwtSecurityToken(
                claims: claims,
                expires: DateTime.Now.AddDays(TokenParameters.EmailTokenLifeTime));

            var cryptedToken = await crypt.Crypt(EmailCypherNameId, token.Payload.SerializeToJson());

            return(cryptedToken);
        }
예제 #11
0
        public virtual string GenerateChangeEmailToken(User user, string email)
        {
            List <Claim> claims = new List <Claim>
            {
                new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
                new Claim(JwtRegisteredClaimNames.Email, email),
                new Claim(JwtRegisteredClaimNames.Jti, CryptoRandomizer.GetRandomString(16))
            };

            var token = new JwtSecurityToken(
                claims: claims.ToArray(),
                expires: DateTime.UtcNow.AddDays(3));

            cryptService.Crypt(CipherSecrets.EmailChange, token.Payload.SerializeToJson());

            return(new JwtSecurityTokenHandler().WriteToken(token));
        }
예제 #12
0
        private string CreateLong2Token(LongSession longSession, out string lat2r)
        {
            lat2r = CryptoRandomizer.GetRandomString(10);

            List <Claim> claims = new List <Claim>
            {
                new Claim(ClaimTypes.NameIdentifier, longSession.UserId.ToString()),
                new Claim(TokenClaimNames.LongToken2Ran, lat2r),
                new Claim(TokenClaimNames.LongToken2Db, longSession.LongToken2),
                new Claim(TokenClaimNames.SessionId, longSession.Id.ToString())
            };

            var token = new JwtSecurityToken(
                claims: claims.ToArray(),
                expires: longSession.ExpirationDate);

            return(cryptService.Crypt(CipherSecrets.Long2Jwt, token.Payload.SerializeToJson()));
        }
예제 #13
0
        public async Task <IActionResult> SignUpAsync([FromForm] RegisterModel model)
        {
            try
            {
                var longSession = CryptoRandomizer.GetRandomString(32);
                var fingerPrint = authService.GetFingerPrint(HttpUtilities.GetDataFromHeaders(HttpContext, HttpConstants.UserAgentHeaderName), longSession);

                var registerResult = await authService.RegisterAsync(model.UserName, model.Email, model.Password, fingerPrint, longSession);

                authService.MakeLongSessionCookies(registerResult.RefreshToken);

                return(Json(registerResult));
            }
            catch (ApiError infoExcetpion)
            {
                return(Unauthorized(infoExcetpion.ex.Description));
            }
        }
예제 #14
0
        public virtual string GenerateChangeEmailToken(User user, string email)
        {
            var key         = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtOptions.SecurityKeyEmailChange));
            var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256Signature);

            List <Claim> claims = new List <Claim>
            {
                new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
                new Claim(JwtRegisteredClaimNames.Email, email),
                new Claim(JwtRegisteredClaimNames.Jti, CryptoRandomizer.GetRandomString(16))
            };

            var token = new JwtSecurityToken(
                issuer: jwtOptions.Issuer,
                audience: jwtOptions.Issuer,
                claims: claims.ToArray(),
                expires: DateTime.Now.AddDays(3),
                signingCredentials: credentials);

            return(new JwtSecurityTokenHandler().WriteToken(token));
        }
예제 #15
0
        public string GenereteJwtToken(string userName, IdentityUser user, List <string> roles)
        {
            var claims = new List <Claim>
            {
                new Claim(ClaimTypes.NameIdentifier, user.Id),
                new Claim(ClaimsIdentity.DefaultNameClaimType, userName),
                new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
                new Claim(CommonConstants.UniqueClaimName, CryptoRandomizer.GetRandomString(16))
            };

            foreach (string role in roles)
            {
                claims.Add(new Claim(ClaimsIdentity.DefaultRoleClaimType, role));
            }

            var signInCreditials = new SigningCredentials(signInEncodingKey.GetKey(),
                                                          signInEncodingKey.SignInAlgorithm);

            var encryptedCreditials = new EncryptingCredentials(jwtEncryptionEncodingKey.GetKey(),
                                                                jwtEncryptionEncodingKey.SigningAlgorithm,
                                                                jwtEncryptionEncodingKey.EncryptingAlgorithm);

            var expires = DateTime.Now.AddMinutes(Convert.ToDouble(tokenLifeTimeOptions.Value.AccessTokenLifeTime));
            var now     = DateTime.UtcNow;

            var token = new JwtSecurityTokenHandler().CreateJwtSecurityToken(
                authOptions.Value.Issuer,
                authOptions.Value.Audience,
                notBefore: now,
                subject: new ClaimsIdentity(claims),
                expires: expires,
                issuedAt: DateTime.Now,
                signingCredentials: signInCreditials,
                encryptingCredentials: encryptedCreditials
                );

            return(new JwtSecurityTokenHandler().WriteToken(token));
        }
예제 #16
0
        private async Task <TokenAndClaimsPrincipal> GenerateShortAuthTokenAsync(User user, string lat2r, string lat2, long sessionId)
        {
            // Generate and issue a JWT token
            var key         = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtOptions.ShortJwtSecurityKey));
            var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256Signature);

            List <Claim> claims = new List <Claim>
            {
                new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
                new Claim(ClaimTypes.Name, user.UserName),
                new Claim(TokenClaimNames.LongToken2Ran, lat2r),
                new Claim(JwtRegisteredClaimNames.Jti, CryptoRandomizer.GetRandomString(DbColumnSizes.BlackListShortToken_TokenId))
            };

            var roleNames = await userManager.GetRolesAsync(user);

            foreach (var role in roleNames)
            {
                claims.Add(new Claim(ClaimTypes.Role, role));
            }

            var token = new JwtSecurityToken(
                issuer: jwtOptions.Issuer,
                audience: jwtOptions.Issuer,
                claims: claims.ToArray(),
                expires: DateTime.UtcNow.AddMinutes(jwtOptions.ShortTokenLiveTimeMinutes),
                signingCredentials: credentials);

            var claimsIdentity  = new ClaimsIdentity(claims, "JwtShortToken");
            var claimsPrincipal = new ClaimsPrincipal(claimsIdentity);

            return(new TokenAndClaimsPrincipal
            {
                ClaimsPrincipal = new SunClaimsPrincipal(claimsPrincipal, rolesCache, sessionId, lat2),
                Token = new JwtSecurityTokenHandler().WriteToken(token)
            });
        }
예제 #17
0
 private string GenerateCaptchaText()
 {
     return(CryptoRandomizer.GetRandomInt(10000, 999999).ToString());
 }
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);

            modelBuilder.Entity <LongSession>().HasKey(x => x.Id);
            modelBuilder.Entity <Cypher>().HasKey(x => x.Id);
            modelBuilder.Entity <StrongKey>().HasKey(x => x.Id);
            modelBuilder.Entity <Picture>().HasKey(x => x.Id);
            modelBuilder.Entity <Message>().HasKey(x => x.Id);
            modelBuilder.Entity <PushTask>().HasKey(x => x.Id);
            modelBuilder.Entity <City>().HasKey(x => x.Id);
            modelBuilder.Entity <Country>().HasKey(x => x.Id);
            modelBuilder.Entity <Like>().HasKey(x => x.Id);
            modelBuilder.Entity <Profile>().HasKey(x => x.Id);
            modelBuilder.Entity <Visit>().HasKey(x => x.Id);
            modelBuilder.Entity <UserPair>().HasKey(x => x.Id);
            modelBuilder.Entity <Cordinate>().HasKey(x => x.Id);
            modelBuilder.Entity <RsaKey>().HasKey(x => x.Id);
            modelBuilder.Entity <UserAccount>().HasKey(x => x.Id);
            modelBuilder.Entity <UserToken>().HasKey(x => x.Id);
            modelBuilder.Entity <Session>().HasKey(x => x.Id);
            modelBuilder.Entity <Connection>().HasKey(x => x.Id);
            modelBuilder.Entity <Dialog>().HasKey(x => x.Id);
            modelBuilder.Entity <AccountingComment>().HasKey(x => x.Id);
            modelBuilder.Entity <Flow>().HasKey(x => x.Id);
            modelBuilder.Entity <AccountingPlan>().HasKey(x => x.Id);
            modelBuilder.Entity <AccountingRecord>().HasKey(x => x.Id);

            modelBuilder.Entity <LongSession>()
            .HasOne(x => x.User)
            .WithMany(x => x.LongSessions);

            modelBuilder.Entity <Message>()
            .HasOne(x => x.Cypher);

            modelBuilder.Entity <PushTask>()
            .HasOne(x => x.User)
            .WithMany(x => x.PushTasks);

            modelBuilder.Entity <City>()
            .HasOne(x => x.Country)
            .WithMany(x => x.Cities);

            modelBuilder.Entity <Like>()
            .HasOne(x => x.User)
            .WithMany(x => x.Likes);

            modelBuilder.Entity <Visit>()
            .HasOne(x => x.User)
            .WithMany(x => x.Visits);

            modelBuilder.Entity <Picture>()
            .HasOne(x => x.User)
            .WithMany(x => x.Pictures);

            modelBuilder.Entity <Message>()
            .HasOne(x => x.Cypher);

            modelBuilder.Entity <Profile>()
            .HasMany(x => x.Characters)
            .WithOne(x => x.Profile);

            modelBuilder.Entity <Profile>()
            .HasOne(x => x.User)
            .WithOne(x => x.Profile)
            .HasForeignKey <Profile>(x => x.UserId);

            modelBuilder.Entity <Profile>()
            .HasOne(x => x.Country)
            .WithMany(x => x.Profiles);

            modelBuilder.Entity <City>()
            .HasMany(x => x.Profiles)
            .WithOne(x => x.City);

            modelBuilder.Entity <Cordinate>()
            .HasOne(x => x.User)
            .WithMany(x => x.Cordinates);

            modelBuilder.Entity <RsaKey>()
            .HasOne(x => x.User)
            .WithMany(x => x.RsaKeys);

            modelBuilder.Entity <User>()
            .HasMany(x => x.UserTokens)
            .WithOne(x => x.User);
            modelBuilder.Entity <User>()
            .HasMany(x => x.Sessions)
            .WithOne(x => x.User);

            modelBuilder.Entity <User>()
            .HasMany(x => x.Sessions)
            .WithOne(x => x.User);

            modelBuilder.Entity <StrongKey>()
            .HasOne(x => x.Cypher);

            modelBuilder.Entity <StrongKey>()
            .HasOne(x => x.User)
            .WithOne(x => x.StrongKey)
            .HasForeignKey <StrongKey>(x => x.UserId);

            modelBuilder.Entity <AccountingRecord>()
            .HasOne(x => x.User)
            .WithMany(x => x.AccountingRecords);


            modelBuilder.Entity <LongSession>().HasIndex(x => x.UserId);
            modelBuilder.Entity <Message>().HasIndex(x => new { x.ReceiverId, x.SenderId });
            modelBuilder.Entity <PushTask>().HasIndex(x => x.UserId);
            modelBuilder.Entity <Like>().HasIndex(x => x.UserId);
            modelBuilder.Entity <Visit>().HasIndex(x => x.UserId);
            modelBuilder.Entity <Profile>().HasIndex(x => x.UserId);
            modelBuilder.Entity <UserPair>().HasIndex(x => new { x.UserId1, x.UserId2 });
            modelBuilder.Entity <Message>().HasIndex(x => x.MessageId);

            modelBuilder.Entity <IdentityRole>().HasData(new IdentityRole[]
            {
                new IdentityRole()
                {
                    Name           = "User",
                    NormalizedName = "USER"
                },
                new IdentityRole()
                {
                    Name           = "Admin",
                    NormalizedName = "ADMIN"
                },
                new IdentityRole()
                {
                    Name           = "ProtocoledUsers",
                    NormalizedName = "PROTOCOLEDUSERS"
                }
            });

            modelBuilder.Entity <Cypher>().HasData(new Cypher[]
            {
                new Cypher()
                {
                    Id     = 1,
                    Secret = CryptoRandomizer.GenerateSecurityKey(32)
                }
            });

            modelBuilder.Entity <UserAccount>().HasData(new UserAccount[]
            {
                new UserAccount()
                {
                    Id       = "1",
                    Login    = "******",
                    Password = "******"
                },
                new UserAccount()
                {
                    Id       = "2",
                    Login    = "******",
                    Password = "******"
                }
            });

            modelBuilder.Entity <AccountingPlan>().HasData(AccountingInitializers.GetAccountingsPlan());
        }
예제 #19
0
        public async Task <CreateFirstMessangerSessionResponse> MakeFirstSessionAsync(CreateMessangerSessionRequest model,
                                                                                      string userId,
                                                                                      string sessionId)
        {
            var savedSessions = await sessionProvider.GetModelBySearchPredicate(x => x.SessionId == sessionId &&
                                                                                x.UserId == userId);

            if (savedSessions != null)
            {
                throw new ApiError(new ServerException("This session is alredy exist"));
            }

            var serverKeys = rsaCypher.GenerateKeys();
            var user       = await userManager.Users.FirstOrDefaultAsync(x => x.Id == userId);

            var serverSession = new Session()
            {
                ClientPublicKey  = model.PublicKey,
                ServerPrivateKey = serverKeys.privateKey,
                ServerPublicKey  = serverKeys.publicKey,
                SessionId        = sessionId,
                UserId           = userId
            };

            var savedStrongKey = await strongKeyProvider.GetModelBySearchPredicate(x => x.UserId == userId);

            if (savedStrongKey != null)
            {
                var savedCypher = await cypherProvider.GetModelBySearchPredicate(x => x.Id == savedStrongKey.CypherId);

                await sessionProvider.CreateOrUpdateAsync(serverSession);

                return(new CreateFirstMessangerSessionResponse()
                {
                    ServerPublicKey = serverKeys.publicKey,
                    CryptedAes = rsaCypher.Crypt(model.PublicKey, savedCypher.Secret.ToUrlSafeBase64())
                });
            }
            else
            {
                await using (var transaction = await transactionProvider.BeginTransactionAsync())
                {
                    try
                    {
                        await sessionProvider.CreateOrUpdateAsync(serverSession);

                        var savedRole = await roleManager.Roles.FirstOrDefaultAsync(x => x.Name == "ProtocoledUsers");

                        await userManager.AddToRoleAsync(user, savedRole.Name);

                        byte[] strongKey = CryptoRandomizer.GenerateSecurityKey(16);

                        var cypher = await cypherProvider.CreateOrUpdateAsync(new Cypher()
                        {
                            Secret = strongKey
                        });

                        var key = await strongKeyProvider.CreateOrUpdateAsync(new StrongKey()
                        {
                            CypherId = cypher.Id,
                            UserId   = user.Id
                        });

                        string strongKeyToCrypt = strongKey.ToUrlSafeBase64();
                        string cryptedAesKey    = rsaCypher.Crypt(model.PublicKey, strongKeyToCrypt);

                        await transaction.CommitAsync();

                        return(new CreateFirstMessangerSessionResponse()
                        {
                            ServerPublicKey = serverKeys.publicKey,
                            CryptedAes = cryptedAesKey
                        });
                    }
                    catch (Exception ex)
                    {
                        await transaction.RollbackAsync();

                        throw new ApiError(new ServerException(ex.Message));
                    }
                }
            }
        }
예제 #20
0
        public string GenerateAesKey()
        {
            var result = CryptoRandomizer.GenerateSecurityKey(32);

            return(result.ToUrlSafeBase64());
        }
예제 #21
0
        public async Task <SunClaimsPrincipal> RenewSecurityTokensAsync(
            HttpContext httpContext,
            User user,
            LongSession longSession = null)
        {
            void GenerateTokens(LongSession longSession1)
            {
                longSession1.LongToken1     = CryptoRandomizer.GetRandomString(LongSession.LongToken1Length);
                longSession1.LongToken2     = CryptoRandomizer.GetRandomString(LongSession.LongToken2Length);
                longSession1.ExpirationDate = DateTime.UtcNow.AddDays(jweOptions.CurrentValue.LongTokenLiveTimeDays);
                httpContext.Request.Headers.TryGetValue("User-Agent", out var userAgent);
                longSession1.DeviceInfo = Parser.GetDefault()?.Parse(userAgent.ToString() ?? "")?.ToString() ?? "";
                longSession1.UpdateDate = DateTime.UtcNow;
            }

            if (longSession == null)
            {
                longSession = new LongSession
                {
                    UserId = user.Id
                };

                GenerateTokens(longSession);

                longSession.Id = await db.InsertWithInt64IdentityAsync(longSession);
            }
            else
            {
                GenerateTokens(longSession);

                await db.UpdateAsync(longSession);
            }


            var lat2Token = CreateLong2Token(longSession, out string lat2r);

            httpContext.Response.Cookies.Append(
                TokenClaimNames.LongToken2CoockiName,
                lat2Token,
                new CookieOptions
            {
                Path        = "/",
                HttpOnly    = true,
                Secure      = globalOptions.CurrentValue.IsHttps,
                IsEssential = true,
                SameSite    = SameSiteMode.Strict,
                Expires     = longSession.ExpirationDate
            }
                );

            TokenAndClaimsPrincipal tokenAndClaimsPrincipal =
                await CreateShortTokenAsync(user, lat2r, longSession.LongToken2, longSession.Id);

            string json = JsonSerializer.Serialize(new
            {
                LongToken            = longSession.LongToken1,
                ShortToken           = tokenAndClaimsPrincipal.Token,
                ShortTokenExpiration = tokenAndClaimsPrincipal.Expiration
            }, SunJson.DefaultJsonSerializerOptions);

            httpContext.Response.Headers.Add(Headers.TokensHeaderName, json);

            return(tokenAndClaimsPrincipal.ClaimsPrincipal);
        }