В.NET System.Threading.Thread.CurrentPrincipal одинаков для разных потоков

Я ищу какой-то общий подход для хранения моего токена JWT на стороне сервера для разных пользователей. Я решил сохранить эти данные в Thread.CurrentPrincipal. Но когда я проверил это, я увидел, что разные клиенты имеют доступ к одному и тому же потоку.

Моделирование нескольких клиентов, которые имеют доступ к моему протестированному сервису wcf:

private static void Main(string[] args)
        {
            List<Thread> threads = new List<Thread>();
            for (int i = 0; i < 20; i++)
            {
                var program = new Program();
                threads.Add(new Thread(program.DoWork));
            }
            foreach (var thread in threads)
            {
                thread.Start();
            }
            Console.ReadLine();
        }

        public void DoWork()
        {
            var client = new AuthenticationClient();
                ClaimsPrincipal claimsPrincipal;
                var _jwtTokenProvider = new JwtTokenProvider();
                Console.WriteLine(client.Connect());
            for (int i = 0; i < 40; i++)
            {
               var result = client.SignIn();
               _jwtTokenProvider.ValidateToken(result, out claimsPrincipal);
               Console.WriteLine(result);
            }
       }

И проверенный метод сервиса:

public string Connect()
        {
            Thread.Sleep(300);
            foreach (var identity in ((ClaimsPrincipal)Thread.CurrentPrincipal).Identities)
            {
                var token = identity.Claims.FirstOrDefault(t => t.Type == "token");
                if (token != null)
                {
                    throw new FaultException<STSFault>(new STSFault(ExceptionsMessages.Message, ErrorCodes.EmptyCredentials), new FaultReason(ExceptionsMessages.Message)); 
                }
            }

            var claimsPrincipal = new ClaimsPrincipal();
            List<Claim> claims = new List<Claim>();
            claims.Add(new Claim("token", "token"));
            var claimIdentity = new ClaimsIdentity(claims);
            claimsPrincipal.AddIdentity(claimIdentity);
            Thread.CurrentPrincipal = claimsPrincipal;
            foreach (var identity in ((ClaimsPrincipal)Thread.CurrentPrincipal).Identities)
            {
                var token = identity.Claims.FirstOrDefault(t => t.Type == "token");
            }
            return Assembly.GetExecutingAssembly().GetName().Version.ToString();
        }

Я не могу понять, почему FaultException бросает. Благодарю.

2 ответа

Это называется контекстом выполнения. Когда вы создаете эти потоки, они "наследуют" принципала от основного потока вашего приложения.

Принципал в вашем главном потоке представляет пользователя с учетными данными, под которым работает ваше приложение.

Посмотрите на этот вопрос.

Вы не можете предполагать, что каждый пользователь клиента будет выполнять свои действия на сервере всегда в одном потоке. Потоки на стороне сервера могут быть повторно использованы для разных запросов от разных клиентов.

Это сильно зависит от того, как вы настраиваете свою службу WCF. См. ConcurrencyMode и InstanceContextMode.

Смотрите также комбинации Instancing и Concurrency

Другие вопросы по тегам