负载平衡器后面的IdentityServer3重定向到外部提供程序以进行Windows身份验证不起作用

时间:2018-07-20 12:57:22

标签: c# owin load-balancing windows-authentication identityserver3

我一直在尝试IdentityServer 3,因此直到我部署负载平衡之后它一直没有问题。

由于尚未被允许使用dotNet Core,我无法使用IdentityServer 4。

我已经将IIS配置为允许Windows身份验证和匿名,这是到目前为止我要提出的:

启动:

public class Startup
{
    X509Certificate2 Cert = Certificate.Load();
    string baseURL = ConfigurationManager.AppSettings["IdServBaseURL"];

    public void Configuration(IAppBuilder app)
    {
        Log.Logger = new LoggerConfiguration()
            .WriteTo.Email("IdServ@company.com", 
                new string[] { "me@company.com" }, 
                "smtp.company.com", 
                restrictedToMinimumLevel: LogEventLevel.Error)
            .CreateLogger();

        app.Use(async (context, next) =>
        {
            try
            {
                await next();
            }
            catch (Exception ex)
            {
                Log.Error(ex, "OWIN Exception");
            }
        });

        var factory = Factory.Configure("MyConnectionString");

        factory.UserService = new Registration<IUserService>(typeof(ExternalRegistrationUserService));

        var options = new IdentityServerOptions
        {
            SigningCertificate = Cert,
            RequireSsl = false,
            Factory = factory,
            AuthenticationOptions = new AuthenticationOptions
            {
                EnableLocalLogin = false,
                EnableSignOutPrompt = false,
                EnablePostSignOutAutoRedirect = true,
                PostSignOutAutoRedirectDelay = 0,
                IdentityProviders = ConfigureIdentityProviders
            },
            IssuerUri = baseURL,
            PublicOrigin = ((new Uri(baseURL))).GetLeftPart(UriPartial.Authority),
            SiteName = "My Id Server"
        };

        app.Map("/windows", ConfigureWindowsTokenProvider);

        app.UseIdentityServer(options);
    }

    private void ConfigureWindowsTokenProvider(IAppBuilder app)
    {
        app.Use(async (context, next) =>
        {
            try
            {
                await next();
            }
            catch (Exception ex)
            {
                Log.Error(ex, "OWIN Exception");
            }
        });

        app.UseWindowsAuthenticationService(new WindowsAuthenticationOptions
        {
            IdpReplyUrl = baseURL + "/was",
            SigningCertificate = Cert,
            EnableOAuth2Endpoint = true
        });
    }

    private void ConfigureIdentityProviders(IAppBuilder app, string signInAsType)
    {
        app.Use(async (context, next) =>
        {
            try
            {
                await next();
            }
            catch (Exception ex)
            {
                Log.Error(ex, "OWIN Exception");
            }
        });

        var wsFederation = new WsFederationAuthenticationOptions
        {
            AuthenticationType = "windows",
            Caption = "Windows",
            SignInAsAuthenticationType = signInAsType,

            MetadataAddress = baseURL + "/windows",
            Wtrealm = "urn:idsrv3"
        };
        app.UseWsFederationAuthentication(wsFederation);
    }
}

工厂:

public class Factory
{
    public static IdentityServerServiceFactory Configure(string connString)
    {
        var efConfig = new EntityFrameworkServiceOptions
        {
            ConnectionString = connString
        };

        var cleanup = new TokenCleanup(efConfig, 10);
        cleanup.Start();

        var factory = new IdentityServerServiceFactory();

        factory.RegisterConfigurationServices(efConfig);
        factory.RegisterOperationalServices(efConfig);

        factory.ConfigureClientStoreCache();
        factory.ConfigureScopeStoreCache();

        return factory;
    }
}

临时用户服务:

public class ExternalRegistrationUserService : UserServiceBase
{
    public class CustomUser
    {
        public string Subject { get; set; }
        public string Provider { get; set; }
        public string ProviderID { get; set; }
        public List<Claim> Claims { get; set; }
    }

    public static List<CustomUser> Users = new List<CustomUser>();

    public override Task AuthenticateExternalAsync(ExternalAuthenticationContext context)
    {
        var user = Users.SingleOrDefault(x => x.Provider == context.ExternalIdentity.Provider && x.ProviderID == context.ExternalIdentity.ProviderId);
        string name = "Unknown";
        if (user == null)
        {
            var nameClaim = context.ExternalIdentity.Claims.First(x => x.Type == Constants.ClaimTypes.Name);
            if (nameClaim != null) name = nameClaim.Value;

            user = new CustomUser
            {
                Subject = Guid.NewGuid().ToString(),
                Provider = context.ExternalIdentity.Provider,
                ProviderID = context.ExternalIdentity.ProviderId,
                Claims = new List<Claim> { new Claim(Constants.ClaimTypes.Name, name) }
            };
            Users.Add(user);
        }

        name = user.Claims.First(x => x.Type == Constants.ClaimTypes.Name).Value;
        context.AuthenticateResult = new AuthenticateResult(user.Subject, name, identityProvider: user.Provider);
        return Task.FromResult(0);
    }

    public override Task GetProfileDataAsync(ProfileDataRequestContext context)
    {
        var user = Users.SingleOrDefault(x => x.Subject == context.Subject.GetSubjectId());
        if (user != null)
        {
            var resultClaims = new List<Claim>();
            resultClaims.AddRange(user.Claims.Where(x => context.RequestedClaimTypes.Contains(x.Type)));

            context.IssuedClaims = resultClaims;
        }

        return Task.FromResult(0);
    }
}

当我尝试从localhost或任何未进行负载平衡的服务器上使用它时,如您在此日志中所见,它工作正常:

[Information] Adding OAuth2 endpoint
[Information] Configuration done.
[Information] Welcome page requested - rendering
[Information] Clearing tokens
[Information] Permissions page requested
[Information] User not authenticated, redirecting to login
[Information] Redirecting to login page
[Information] Login page requested
[Information] local login disabled for the client
[Information] only one provider for client
[Information] redirecting to provider URL: "https://myserver.com/IdSrv/external?provider=windows&signin=b0f68735e23333b30cac91da12cf300c"
[Information] External login requested for provider: "windows"
[Information] Triggering challenge for external identity provider
[Information] Start WS-Federation metadata request
[Information] Start WS-Federation request
[Information] User is anonymous. Triggering authentication
[Information] Start WS-Federation request
[Information] Sign-in request
[Information] Creating WS-Federation signin response
[Information] Callback invoked from external identity provider
[Information] external user provider: "windows", provider ID: "S-1-5-21-xxxxx-xxxxxxxx-xxxxxxxx-xxxxxxx"
[Information] External identity successfully validated by user service
[Information] Calling PostAuthenticateAsync on the user service
[Information] issuing primary signin cookie
[Information] redirecting to: https://myserver.com/IdSrv/permissions
[Information] Permissions page requested
[Information] Rendering permissions page
[Information] Clearing tokens
[Information] Start token request
[Information] Secret id found: "client1"
[Information] Client validation success
[Information] Start token request validation
[Information] Start client credentials token request validation
[Information] Client credentials token request validation success
[Information] Token request validation success  {
  "ClientId": "client1",
  "ClientName": "Clien1",
  "GrantType": "client_credentials",
  "Scopes": "myscope",
  "Raw": {
    "client_id": "client1",
    "client_secret": "******",
    "scope": "myscope",
    "grant_type": "client_credentials"
  }
}
[Information] Creating token response
[Information] Processing token request
[Information] End token request
[Information] Returning token response.
[Information] Clearing tokens

但是,一旦我在负载平衡的服务器中部署了任何使用client_credentials流的东西,似乎都无法正常工作,但是任何试图验证用户身份的东西都将停止工作。它不再对用户进行身份验证。这是错误日志:

[Information] Welcome page requested - rendering
[Information] Permissions page requested
[Information] User not authenticated, redirecting to login
[Information] Redirecting to login page
[Information] Login page requested
[Information] local login disabled for the client
[Information] only one provider for client
[Information] redirecting to provider URL: "https://mybalancedserver.com/Idsrv/external?provider=windows&signin=dbe3e00a7490584e1568471b9ed48948"
[Information] External login requested for provider: "windows"
[Information] Triggering challenge for external identity provider
[Error] OWIN Exception
System.InvalidOperationException: IDX10803: Unable to create to obtain configuration from: 'https://mybalancedserver.com/Idsrv/windows'. ---> System.IO.IOException: Unable to get document from: https://mybalancedserver.com/Idsrv/windows ---> System.Net.Http.HttpRequestException: An error occurred while sending the request. ---> System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a send. ---> System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. ---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
   at System.Net.Sockets.Socket.BeginReceive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags, AsyncCallback callback, Object state)
   at System.Net.Sockets.NetworkStream.BeginRead(Byte[] buffer, Int32 offset, Int32 size, AsyncCallback callback, Object state)
   --- End of inner exception stack trace ---
   at System.Net.TlsStream.EndWrite(IAsyncResult asyncResult)
   at System.Net.ConnectStream.WriteHeadersCallback(IAsyncResult ar)
   --- End of inner exception stack trace ---
   at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
   at System.Net.Http.HttpClientHandler.GetResponseCallback(IAsyncResult ar)
   --- End of inner exception stack trace ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.<GetDocumentAsync>d__0.MoveNext()
   --- End of inner exception stack trace ---
   at Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.<GetDocumentAsync>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.IdentityModel.Protocols.WsFederationConfigurationRetriever.<GetAsync>d__1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.IdentityModel.Protocols.ConfigurationManager`1.<GetConfigurationAsync>d__3.MoveNext()
   --- End of inner exception stack trace ---
   at Microsoft.IdentityModel.Protocols.ConfigurationManager`1.<GetConfigurationAsync>d__3.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Owin.Security.WsFederation.WsFederationAuthenticationHandler.<ApplyResponseChallengeAsync>d__c.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Owin.Security.Infrastructure.AuthenticationHandler.<ApplyResponseCoreAsync>d__b.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Owin.Security.Infrastructure.AuthenticationHandler.<ApplyResponseAsync>d__8.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Owin.Security.Infrastructure.AuthenticationHandler.<TeardownAsync>d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Owin.Security.Infrastructure.AuthenticationMiddleware`1.<Invoke>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at MDCR.IdentityServer.Startup.<>c.<<ConfigureIdentityProviders>b__4_0>d.MoveNext() in C:\Startup.cs:line 110

[Information] External login requested for provider: "windows"
[Information] Triggering challenge for external identity provider

[Error] OWIN Exception
System.InvalidOperationException: IDX10803: Unable to create to obtain configuration from: 'https://mybalancedserver.com/Idsrv/windows'.
   at Microsoft.IdentityModel.Protocols.ConfigurationManager`1.<GetConfigurationAsync>d__3.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Owin.Security.WsFederation.WsFederationAuthenticationHandler.<ApplyResponseChallengeAsync>d__c.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Owin.Security.Infrastructure.AuthenticationHandler.<ApplyResponseCoreAsync>d__b.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Owin.Security.Infrastructure.AuthenticationHandler.<ApplyResponseAsync>d__8.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Owin.Security.Infrastructure.AuthenticationHandler.<TeardownAsync>d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Owin.Security.Infrastructure.AuthenticationMiddleware`1.<Invoke>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at MDCR.IdentityServer.Startup.<>c.<<ConfigureIdentityProviders>b__4_0>d.MoveNext() in C:\Startup.cs:line 110

[Information] External login requested for provider: "windows"
[Information] Triggering challenge for external identity provider

[Error] OWIN Exception
System.InvalidOperationException: IDX10803: Unable to create to obtain configuration from: 'https://mybalancedserver.com/Idsrv/windows'.
   at Microsoft.IdentityModel.Protocols.ConfigurationManager`1.<GetConfigurationAsync>d__3.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Owin.Security.WsFederation.WsFederationAuthenticationHandler.<ApplyResponseChallengeAsync>d__c.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Owin.Security.Infrastructure.AuthenticationHandler.<ApplyResponseCoreAsync>d__b.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Owin.Security.Infrastructure.AuthenticationHandler.<ApplyResponseAsync>d__8.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Owin.Security.Infrastructure.AuthenticationHandler.<TeardownAsync>d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Owin.Security.Infrastructure.AuthenticationMiddleware`1.<Invoke>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at MDCR.IdentityServer.Startup.<>c.<<ConfigureIdentityProviders>b__4_0>d.MoveNext() in C:\Startup.cs:line 110

0 个答案:

没有答案