public async Task ChallengeCanSetUserStateThroughProperties(string userState)
        {
            var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider(NullLoggerFactory.Instance).CreateProtector("OIDCTest"));
            var settings    = new TestSettings(o =>
            {
                o.ClientId        = "Test Id";
                o.Authority       = TestServerBuilder.DefaultAuthority;
                o.StateDataFormat = stateFormat;
            });

            var properties = new AuthenticationProperties();

            properties.Items.Add(OpenIdConnectDefaults.UserstatePropertiesKey, userState);

            var server      = settings.CreateTestServer(properties);
            var transaction = await server.SendAsync(TestServerBuilder.TestHost + TestServerBuilder.ChallengeWithProperties);

            var res = transaction.Response;

            Assert.Equal(HttpStatusCode.Redirect, res.StatusCode);
            Assert.NotNull(res.Headers.Location);

            var values           = settings.ValidateChallengeRedirect(res.Headers.Location);
            var actualState      = values[OpenIdConnectParameterNames.State];
            var actualProperties = stateFormat.Unprotect(actualState);

            Assert.Equal(userState ?? string.Empty, actualProperties.Items[OpenIdConnectDefaults.UserstatePropertiesKey]);
        }
        public async Task ChallengeRedirectIsIssuedCorrectly()
        {
            var settings = new TestSettings(
                opt =>
            {
                opt.Authority            = TestServerBuilder.DefaultAuthority;
                opt.AuthenticationMethod = OpenIdConnectRedirectBehavior.RedirectGet;
                opt.ClientId             = "Test Id";
            });

            var server      = settings.CreateTestServer();
            var transaction = await server.SendAsync(ChallengeEndpoint);

            var res = transaction.Response;

            Assert.Equal(HttpStatusCode.Redirect, res.StatusCode);
            Assert.NotNull(res.Headers.Location);

            settings.ValidateChallengeRedirect(
                res.Headers.Location,
                OpenIdConnectParameterNames.ClientId,
                OpenIdConnectParameterNames.ResponseType,
                OpenIdConnectParameterNames.ResponseMode,
                OpenIdConnectParameterNames.Scope,
                OpenIdConnectParameterNames.RedirectUri,
                OpenIdConnectParameterNames.SkuTelemetry,
                OpenIdConnectParameterNames.VersionTelemetry);
        }
        public async Task Challenge_WithDefaultMaxAge_HasExpectedMaxAgeParam()
        {
            var settings = new TestSettings(
                opt =>
            {
                opt.ClientId  = "Test Id";
                opt.Authority = TestServerBuilder.DefaultAuthority;
            });

            var server      = settings.CreateTestServer();
            var transaction = await server.SendAsync(ChallengeEndpoint);

            var res = transaction.Response;

            settings.ValidateChallengeRedirect(
                res.Headers.Location,
                OpenIdConnectParameterNames.MaxAge);
        }
        public async Task Challenge_HasExpectedPromptParam()
        {
            var settings = new TestSettings(opt =>
            {
                opt.ClientId  = "Test Id";
                opt.Authority = TestServerBuilder.DefaultAuthority;
                opt.Prompt    = "consent";
            });

            var server      = settings.CreateTestServer();
            var transaction = await server.SendAsync(ChallengeEndpoint);

            var res = transaction.Response;

            Assert.Equal(HttpStatusCode.Redirect, res.StatusCode);
            settings.ValidateChallengeRedirect(res.Headers.Location, OpenIdConnectParameterNames.Prompt);
            Assert.Contains("prompt=consent", res.Headers.Location.Query);
        }
        public async Task Challenge_WithSpecificMaxAge_HasExpectedMaxAgeParam()
        {
            var settings = new TestSettings(
                opt =>
            {
                opt.ClientId  = "Test Id";
                opt.Authority = TestServerBuilder.DefaultAuthority;
                opt.MaxAge    = TimeSpan.FromMinutes(20);
            });

            var server      = settings.CreateTestServer();
            var transaction = await server.SendAsync(ChallengeEndpoint);

            var res = transaction.Response;

            Assert.Equal(HttpStatusCode.Redirect, res.StatusCode);
            settings.ValidateChallengeRedirect(
                res.Headers.Location,
                OpenIdConnectParameterNames.MaxAge);
        }
        public async Task Challenge_HasOverwrittenMaxAgeParaFromBaseAuthenticationPropertiesm()
        {
            var settings = new TestSettings(opt =>
            {
                opt.ClientId  = "Test Id";
                opt.Authority = TestServerBuilder.DefaultAuthority;
                opt.MaxAge    = TimeSpan.FromSeconds(500);
            });
            var properties = new AuthenticationProperties();

            properties.SetParameter(OpenIdConnectChallengeProperties.MaxAgeKey, TimeSpan.FromSeconds(1234));

            var server      = settings.CreateTestServer(properties);
            var transaction = await server.SendAsync(TestServerBuilder.TestHost + TestServerBuilder.ChallengeWithProperties);

            var res = transaction.Response;

            Assert.Equal(HttpStatusCode.Redirect, res.StatusCode);
            settings.ValidateChallengeRedirect(res.Headers.Location);
            Assert.Contains("max_age=1234", res.Headers.Location.Query);
        }
        public async Task Challenge_HasOverwrittenPromptParamFromBaseAuthenticationProperties()
        {
            var settings = new TestSettings(opt =>
            {
                opt.ClientId  = "Test Id";
                opt.Authority = TestServerBuilder.DefaultAuthority;
                opt.Prompt    = "consent";
            });
            var properties = new AuthenticationProperties();

            properties.SetParameter(OpenIdConnectChallengeProperties.PromptKey, "login");

            var server      = settings.CreateTestServer(properties);
            var transaction = await server.SendAsync(TestServerBuilder.TestHost + TestServerBuilder.ChallengeWithProperties);

            var res = transaction.Response;

            Assert.Equal(HttpStatusCode.Redirect, res.StatusCode);
            settings.ValidateChallengeRedirect(res.Headers.Location);
            Assert.Contains("prompt=login", res.Headers.Location.Query);
        }
        public async Task OnRedirectToIdentityProviderEventCanReplaceValues()
        {
            var newClientId = Guid.NewGuid().ToString();

            var settings = new TestSettings(
                opts =>
            {
                opts.ClientId  = "Test Id";
                opts.Authority = TestServerBuilder.DefaultAuthority;
                opts.Events    = new OpenIdConnectEvents()
                {
                    OnRedirectToIdentityProvider = context =>
                    {
                        context.ProtocolMessage.ClientId = newClientId;
                        return(Task.FromResult(0));
                    }
                };
            }
                );

            var server      = settings.CreateTestServer();
            var transaction = await server.SendAsync(ChallengeEndpoint);

            var res = transaction.Response;

            Assert.Equal(HttpStatusCode.Redirect, res.StatusCode);
            Assert.NotNull(res.Headers.Location);

            settings.ValidateChallengeRedirect(
                res.Headers.Location,
                OpenIdConnectParameterNames.ResponseType,
                OpenIdConnectParameterNames.ResponseMode,
                OpenIdConnectParameterNames.Scope,
                OpenIdConnectParameterNames.RedirectUri);

            var actual = res.Headers.Location.Query.Trim('?').Split('&').Single(seg => seg.StartsWith($"{OpenIdConnectParameterNames.ClientId}="));

            Assert.Equal($"{OpenIdConnectParameterNames.ClientId}={newClientId}", actual);
        }
        public async Task OnRedirectToIdentityProviderEventCanSetState(string userState)
        {
            var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider(NullLoggerFactory.Instance).CreateProtector("OIDCTest"));
            var settings    = new TestSettings(opt =>
            {
                opt.StateDataFormat = stateFormat;
                opt.ClientId        = "Test Id";
                opt.Authority       = TestServerBuilder.DefaultAuthority;
                opt.Events          = new OpenIdConnectEvents()
                {
                    OnRedirectToIdentityProvider = context =>
                    {
                        context.ProtocolMessage.State = userState;
                        return(Task.FromResult(0));
                    }
                };
            });

            var server      = settings.CreateTestServer();
            var transaction = await server.SendAsync(ChallengeEndpoint);

            var res = transaction.Response;

            Assert.Equal(HttpStatusCode.Redirect, res.StatusCode);
            Assert.NotNull(res.Headers.Location);

            var values           = settings.ValidateChallengeRedirect(res.Headers.Location);
            var actualState      = values[OpenIdConnectParameterNames.State];
            var actualProperties = stateFormat.Unprotect(actualState);

            if (userState != null)
            {
                Assert.Equal(userState, actualProperties.Items[OpenIdConnectDefaults.UserstatePropertiesKey]);
            }
            else
            {
                Assert.False(actualProperties.Items.ContainsKey(OpenIdConnectDefaults.UserstatePropertiesKey));
            }
        }
        public async Task Challenge_HasOverwrittenScopeParamFromBaseAuthenticationProperties()
        {
            var settings = new TestSettings(opt =>
            {
                opt.ClientId  = "Test Id";
                opt.Authority = TestServerBuilder.DefaultAuthority;
                opt.Scope.Clear();
                opt.Scope.Add("foo");
                opt.Scope.Add("bar");
            });
            var properties = new AuthenticationProperties();

            properties.SetParameter(OpenIdConnectChallengeProperties.ScopeKey, new string[] { "baz", "qux" });

            var server      = settings.CreateTestServer(properties);
            var transaction = await server.SendAsync(TestServerBuilder.TestHost + TestServerBuilder.ChallengeWithProperties);

            var res = transaction.Response;

            Assert.Equal(HttpStatusCode.Redirect, res.StatusCode);
            settings.ValidateChallengeRedirect(res.Headers.Location);
            Assert.Contains("scope=baz%20qux", res.Headers.Location.Query);
        }
        public async Task OnRedirectToIdentityProviderEventIsHit()
        {
            var eventIsHit = false;
            var settings   = new TestSettings(
                opts =>
            {
                opts.ClientId  = "Test Id";
                opts.Authority = TestServerBuilder.DefaultAuthority;
                opts.Events    = new OpenIdConnectEvents()
                {
                    OnRedirectToIdentityProvider = context =>
                    {
                        eventIsHit = true;
                        return(Task.FromResult(0));
                    }
                };
            }
                );

            var server      = settings.CreateTestServer();
            var transaction = await server.SendAsync(ChallengeEndpoint);

            Assert.True(eventIsHit);

            var res = transaction.Response;

            Assert.Equal(HttpStatusCode.Redirect, res.StatusCode);
            Assert.NotNull(res.Headers.Location);

            settings.ValidateChallengeRedirect(
                res.Headers.Location,
                OpenIdConnectParameterNames.ClientId,
                OpenIdConnectParameterNames.ResponseType,
                OpenIdConnectParameterNames.ResponseMode,
                OpenIdConnectParameterNames.Scope,
                OpenIdConnectParameterNames.RedirectUri);
        }