3

我正在寻找一些通用方法来为不同的用户在服务器端存储我的 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。谢谢。

4

2 回答 2

4

这称为执行上下文。当您创建这些线程时,它们会从您的应用程序的主线程“继承”主体。

主线程中的主体代表运行您的应用程序的凭据的用户。

看看这个问题。

于 2013-11-08T10:38:10.520 回答
1

您不能假设每个客户端用户总是在同一个线程中在服务器上执行其操作。服务器端的线程可能会被不同客户端的不同请求重用。

这在很大程度上取决于您如何配置 WCF 服务。请参阅ConcurrencyModeInstanceContextMode

另请参阅实例化和并发的组合

于 2013-11-08T10:49:31.663 回答