Adding verification for openIdconnect logout flow
As well removed the logic to wait for the creation of the db file in userprofile folder as we now have retry logic.
This commit is contained in:
parent
0d673eafc9
commit
2c881cf6a6
|
|
@ -437,7 +437,7 @@ namespace MusicStore.Controllers
|
|||
// TODO: Currently SignInManager.SignOut does not sign out OpenIdc and does not have a way to pass in a specific
|
||||
// AuthType to sign out.
|
||||
var appEnv = Context.RequestServices.GetService<IHostingEnvironment>();
|
||||
if (appEnv.EnvironmentName == "OpenIdConnect")
|
||||
if (appEnv.EnvironmentName.StartsWith("OpenIdConnect"))
|
||||
{
|
||||
Response.SignOut("OpenIdConnect");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ namespace E2ETests
|
|||
|
||||
private static string APP_RELATIVE_PATH = Path.Combine("..", "..", "src", "MusicStore");
|
||||
|
||||
public static Process StartApplication(StartParameters startParameters, string identityDbName, ILogger logger)
|
||||
public static Process StartApplication(StartParameters startParameters, ILogger logger)
|
||||
{
|
||||
startParameters.ApplicationPath = Path.GetFullPath(Path.Combine(Environment.CurrentDirectory, APP_RELATIVE_PATH));
|
||||
|
||||
|
|
@ -158,7 +158,7 @@ namespace E2ETests
|
|||
}
|
||||
else
|
||||
{
|
||||
hostProcess = StartSelfHost(startParameters, identityDbName, logger);
|
||||
hostProcess = StartSelfHost(startParameters, logger);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -205,6 +205,13 @@ namespace E2ETests
|
|||
|
||||
var hostProcess = Process.Start(startInfo);
|
||||
logger.WriteInformation("Started {0}. Process Id : {1}", hostProcess.MainModule.FileName, hostProcess.Id);
|
||||
|
||||
if (hostProcess.HasExited)
|
||||
{
|
||||
logger.WriteError("Host process {processName} exited with code {exitCode} or failed to start.", startInfo.FileName, hostProcess.ExitCode);
|
||||
throw new Exception("Failed to start host");
|
||||
}
|
||||
|
||||
return hostProcess;
|
||||
}
|
||||
|
||||
|
|
@ -256,7 +263,7 @@ namespace E2ETests
|
|||
return hostProcess;
|
||||
}
|
||||
|
||||
private static Process StartSelfHost(StartParameters startParameters, string identityDbName, ILogger logger)
|
||||
private static Process StartSelfHost(StartParameters startParameters, ILogger logger)
|
||||
{
|
||||
var commandName = startParameters.ServerType == ServerType.WebListener ? "web" : "kestrel";
|
||||
logger.WriteInformation("Executing klr.exe --appbase {appPath} \"Microsoft.Framework.ApplicationHost\" {command}", startParameters.ApplicationPath, commandName);
|
||||
|
|
@ -273,6 +280,12 @@ namespace E2ETests
|
|||
//Sometimes reading MainModule returns null if called immediately after starting process.
|
||||
Thread.Sleep(1 * 1000);
|
||||
|
||||
if (hostProcess.HasExited)
|
||||
{
|
||||
logger.WriteError("Host process {processName} exited with code {exitCode} or failed to start.", startInfo.FileName, hostProcess.ExitCode);
|
||||
throw new Exception("Failed to start host");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
logger.WriteInformation("Started {fileName}. Process Id : {processId}", hostProcess.MainModule.FileName, hostProcess.Id);
|
||||
|
|
@ -282,8 +295,6 @@ namespace E2ETests
|
|||
logger.WriteWarning("Cannot access 64 bit modules from a 32 bit process. Failed with following message.", win32Exception);
|
||||
}
|
||||
|
||||
WaitTillDbCreated(identityDbName, logger);
|
||||
|
||||
return hostProcess;
|
||||
}
|
||||
|
||||
|
|
@ -342,50 +353,6 @@ namespace E2ETests
|
|||
logger.WriteInformation("kpm bundle finished with exit code : {exitCode}", hostProcess.ExitCode);
|
||||
}
|
||||
|
||||
//In case of self-host application activation happens immediately unlike iis where activation happens on first request.
|
||||
//So in self-host case, we need a way to block the first request until the application is initialized. In MusicStore application's case,
|
||||
//identity DB creation is pretty much the last step of application setup. So waiting on this event will help us wait efficiently.
|
||||
private static void WaitTillDbCreated(string identityDbName, ILogger logger)
|
||||
{
|
||||
var identityDBFullPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), identityDbName + ".mdf");
|
||||
if (File.Exists(identityDBFullPath))
|
||||
{
|
||||
logger.WriteWarning("Database file '{mdf}' exists. Proceeding with the tests.", identityDBFullPath);
|
||||
return;
|
||||
}
|
||||
|
||||
logger.WriteInformation("Watching for the DB file '{mdf}'", identityDBFullPath);
|
||||
var dbWatch = new FileSystemWatcher(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), identityDbName + ".mdf");
|
||||
dbWatch.EnableRaisingEvents = true;
|
||||
|
||||
try
|
||||
{
|
||||
if (!File.Exists(identityDBFullPath))
|
||||
{
|
||||
//Wait for a maximum of 1 minute assuming the slowest cold start.
|
||||
var watchResult = dbWatch.WaitForChanged(WatcherChangeTypes.Created, 60 * 1000);
|
||||
if (watchResult.ChangeType == WatcherChangeTypes.Created)
|
||||
{
|
||||
//This event is fired immediately after the localdb file is created. Give it a while to finish populating data and start the application.
|
||||
Thread.Sleep(5 * 1000);
|
||||
logger.WriteInformation("Database file created '{mdf}'. Proceeding with the tests.", identityDBFullPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.WriteWarning("Database file '{mdf}' not created", identityDBFullPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
logger.WriteWarning("Received this exception while watching for Database file", exception);
|
||||
}
|
||||
finally
|
||||
{
|
||||
dbWatch.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public static void CleanUpApplication(StartParameters startParameters, Process hostProcess, string musicStoreDbName, ILogger logger)
|
||||
{
|
||||
if (startParameters.ServerType == ServerType.IISNativeModule ||
|
||||
|
|
|
|||
|
|
@ -31,8 +31,7 @@ namespace E2ETests
|
|||
if (exception.InnerException is HttpRequestException || exception.InnerException is WebException)
|
||||
{
|
||||
logger.WriteWarning("Failed to complete the request.", exception);
|
||||
var waitTimeInMilliSeconds = (RunningOnMono ? 7 : 1) * 1000;
|
||||
Thread.Sleep(waitTimeInMilliSeconds); //Wait for a second before retry
|
||||
Thread.Sleep(7 * 1000); //Wait for a while before retry.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,6 +82,25 @@ namespace E2ETests
|
|||
//This action requires admin permissions. If notifications are fired this permission is granted
|
||||
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
|
||||
_logger.WriteInformation("Middleware notifications were fired successfully");
|
||||
|
||||
_logger.WriteInformation("Verifying the OpenIdConnect logout flow..");
|
||||
response = _httpClient.GetAsync(string.Empty).Result;
|
||||
ThrowIfResponseStatusNotOk(response);
|
||||
responseContent = response.Content.ReadAsStringAsync().Result;
|
||||
ValidateLayoutPage(responseContent);
|
||||
formParameters = new List<KeyValuePair<string, string>>
|
||||
{
|
||||
new KeyValuePair<string, string>("__RequestVerificationToken", HtmlDOMHelper.RetrieveAntiForgeryToken(responseContent, "/Account/LogOff")),
|
||||
};
|
||||
|
||||
content = new FormUrlEncodedContent(formParameters.ToArray());
|
||||
response = _httpClient.PostAsync("Account/LogOff", content).Result;
|
||||
Assert.Null(_httpClientHandler.CookieContainer.GetCookies(new Uri(_applicationBaseUrl)).GetCookieWithName(".AspNet.Microsoft.AspNet.Identity.Application"));
|
||||
Assert.Equal<string>(
|
||||
"https://login.windows.net/4afbc689-805b-48cf-a24c-d4aa3248a248/oauth2/logout",
|
||||
response.RequestMessage.RequestUri.AbsoluteUri.Replace(response.RequestMessage.RequestUri.Query, string.Empty));
|
||||
queryItems = new ReadableStringCollection(QueryHelpers.ParseQuery(response.RequestMessage.RequestUri.Query));
|
||||
Assert.Equal<string>(_applicationBaseUrl + "Account/Login", queryItems["post_logout_redirect_uri"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -56,7 +56,9 @@ namespace E2ETests
|
|||
_logger.WriteInformation("Application initialization successful.");
|
||||
|
||||
_logger.WriteInformation("Application runtime information");
|
||||
var runtimeInfo = _httpClient.GetAsync("runtimeinfo").Result.Content.ReadAsStringAsync().Result;
|
||||
var runtimeResponse = _httpClient.GetAsync("runtimeinfo").Result;
|
||||
ThrowIfResponseStatusNotOk(runtimeResponse);
|
||||
var runtimeInfo = runtimeResponse.Content.ReadAsStringAsync().Result;
|
||||
_logger.WriteInformation(runtimeInfo);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ namespace E2ETests
|
|||
|
||||
try
|
||||
{
|
||||
hostProcess = DeploymentUtility.StartApplication(_startParameters, musicStoreDbName, _logger);
|
||||
hostProcess = DeploymentUtility.StartApplication(_startParameters, _logger);
|
||||
|
||||
_httpClientHandler = new HttpClientHandler() { UseDefaultCredentials = true };
|
||||
_httpClient = new HttpClient(_httpClientHandler) { BaseAddress = new Uri(applicationBaseUrl) };
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ namespace E2ETests
|
|||
{
|
||||
[ConditionalTheory]
|
||||
[FrameworkSkipCondition(RuntimeFrameworks.Mono)]
|
||||
[InlineData(ServerType.IISExpress, RuntimeFlavor.CoreClr, RuntimeArchitecture.x86, "http://localhost:5001/")]
|
||||
[InlineData(ServerType.IISExpress, RuntimeFlavor.DesktopClr, RuntimeArchitecture.x86, "http://localhost:5001/")]
|
||||
public void OpenIdConnect_OnX86(ServerType serverType, RuntimeFlavor runtimeFlavor, RuntimeArchitecture architecture, string applicationBaseUrl)
|
||||
{
|
||||
OpenIdConnectTestSuite(serverType, runtimeFlavor, architecture, applicationBaseUrl);
|
||||
|
|
@ -55,7 +55,7 @@ namespace E2ETests
|
|||
|
||||
try
|
||||
{
|
||||
hostProcess = DeploymentUtility.StartApplication(_startParameters, musicStoreDbName, _logger);
|
||||
hostProcess = DeploymentUtility.StartApplication(_startParameters, _logger);
|
||||
if (serverType == ServerType.IISNativeModule || serverType == ServerType.IIS)
|
||||
{
|
||||
// Accomodate the vdir name.
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ namespace E2ETests
|
|||
|
||||
try
|
||||
{
|
||||
hostProcess = DeploymentUtility.StartApplication(_startParameters, musicStoreDbName, _logger);
|
||||
hostProcess = DeploymentUtility.StartApplication(_startParameters, _logger);
|
||||
|
||||
_httpClientHandler = new HttpClientHandler() { UseDefaultCredentials = true };
|
||||
_httpClient = new HttpClient(_httpClientHandler) { BaseAddress = new Uri(applicationBaseUrl) };
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ namespace E2ETests
|
|||
|
||||
try
|
||||
{
|
||||
hostProcess = DeploymentUtility.StartApplication(_startParameters, musicStoreDbName, _logger);
|
||||
hostProcess = DeploymentUtility.StartApplication(_startParameters, _logger);
|
||||
if (serverType == ServerType.IISNativeModule || serverType == ServerType.IIS)
|
||||
{
|
||||
// Accomodate the vdir name.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.AspNet.Security.Notifications;
|
||||
using Microsoft.AspNet.Security.OpenIdConnect;
|
||||
using Microsoft.IdentityModel.Protocols;
|
||||
|
|
@ -58,6 +59,13 @@ namespace MusicStore.Mocks.OpenIdConnect
|
|||
(RedirectToIdentityProviderNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> context)
|
||||
{
|
||||
notificationsFired.Add(nameof(RedirectToIdentityProvider));
|
||||
|
||||
if (context.ProtocolMessage.RequestType == OpenIdConnectRequestType.LogoutRequest)
|
||||
{
|
||||
context.ProtocolMessage.PostLogoutRedirectUri =
|
||||
context.Request.Scheme + "://" + context.Request.Host + context.Request.PathBase + new PathString("/Account/Login");
|
||||
}
|
||||
|
||||
await Task.FromResult(0);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue