使用无效网络凭据的Kerberos身份验证导致第二次调用后出现无法解释的超时

问题描述 投票:1回答:1

我有一个问题,在同一参数下使用KerberosWSTrustBinding绑定两次调用WSTrustChannel.Issue不会产生相同的结果。第一个调用导致异常“安全包中没有可用的凭据”,但是第二个调用导致超时。似乎第一个调用没有清除一些资源,并使应用程序处于怪异状态。

有什么问题的主意吗?

这里是代码:

    using System;
    using System.IdentityModel.Tokens;
    using System.ServiceModel;
    using System.ServiceModel.Security;
    using Microsoft.IdentityModel.Protocols.WSTrust;
    using Microsoft.IdentityModel.Protocols.WSTrust.Bindings;
    using Microsoft.IdentityModel.SecurityTokenService;
    using System.Security.Principal;
    using System.Net;
    using System.ServiceModel.Channels;

    namespace Test
    {
        class Program
        {
            static void Main(string[] args)
            {
                GetToken();
                GetToken();
            }

            private static void GetToken()
            {
                try
                {
                    var credentials = CredentialCache.DefaultNetworkCredentials;

                    var binding = new KerberosWSTrustBinding(SecurityMode.TransportWithMessageCredential);
                    binding.CloseTimeout = TimeSpan.FromSeconds(10);
                    binding.OpenTimeout = TimeSpan.FromSeconds(10);
                    binding.ReceiveTimeout = TimeSpan.FromSeconds(10);
                    binding.SendTimeout = TimeSpan.FromSeconds(10);

                    var trustChannelFactory = new WSTrustChannelFactory(binding, new EndpointAddress("https://www.google.com/adfs/services/trust/13/kerberosmixed")); //Changing for a valid ADFS server address does not affect the behavior
                    trustChannelFactory.TrustVersion = TrustVersion.WSTrust13;
                    trustChannelFactory.Credentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation;
                    trustChannelFactory.Credentials.Windows.ClientCredential = credentials;
                    trustChannelFactory.ConfigureChannelFactory();

                    var wsTrustChannel = (WSTrustChannel)trustChannelFactory.CreateChannel();
                    var requestSecurityToken = new RequestSecurityToken(WSTrust13Constants.RequestTypes.Issue, KeyTypes.Bearer);
                    requestSecurityToken.AppliesTo = new EndpointAddress(new Uri("https://DontCare"));

                    var requestSecurityTokenResponse = new RequestSecurityTokenResponse();
                    var token = wsTrustChannel.Issue(requestSecurityToken, out requestSecurityTokenResponse);

                    Console.WriteLine("[SUCCESS] Kerberos");
                }
                catch (Exception ex)
                {
                    Console.WriteLine("[FAIL] Kerberos");
                    Console.WriteLine(GetExceptionMessages(ex));
                }
            }
            public static string GetExceptionMessages(Exception exception, string separator = ". ")
            {
                StringBuilder sb = new StringBuilder();

                string previousExceptionMessage = null;

                Exception currentException = exception;

                while (currentException != null)
                {
                    string currentExceptionMessage = currentException.Message;

                    if (currentExceptionMessage != previousExceptionMessage)
                    {
                        if (sb.Length > 0)
                        {
                            sb.Append(separator);
                        }

                        sb.Append(currentExceptionMessage);
                    }

                    previousExceptionMessage = currentExceptionMessage;

                    currentException = currentException.InnerException;
                }

                return sb.ToString();
            }

        }
    }
wcf .net-3.5 wif kerberos adfs2.0
1个回答
0
投票

可笑的是,六年后我不记得我最初的问题时再次遇到了同样的问题...

更新:6年后的事件,使用wif的更新版本无法单独解决此问题。

由于此问题仍未解决,所以知道第二个呼叫将失败,因此我将超时设置为1毫秒,并立即重新发出了呼叫(令人惊讶的是重新发出呼叫将起作用)

            binding.CloseTimeout = TimeSpan.FromMilliseconds(1);
            binding.OpenTimeout = TimeSpan.FromMilliseconds(1);
            binding.ReceiveTimeout = TimeSpan.FromMilliseconds(1);
            binding.SendTimeout = TimeSpan.FromMilliseconds(1);

然后是第三个调用(或使用默认值)

            binding.CloseTimeout = TimeSpan.FromMilliseconds(60000);
            binding.OpenTimeout = TimeSpan.FromMilliseconds(60000);
            binding.ReceiveTimeout = TimeSpan.FromMilliseconds(60000);
            binding.SendTimeout = TimeSpan.FromMilliseconds(60000);
© www.soinside.com 2019 - 2024. All rights reserved.