我一直在尝试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