Пример #1
0
        public async Task ReplyPathWillRejectIfAccessTokenIsMissing()
        {
            var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("GoogleTest"));
            var server      = CreateServer(options =>
            {
                options.ClientId               = "Test Id";
                options.ClientSecret           = "Test Secret";
                options.StateDataFormat        = stateFormat;
                options.BackchannelHttpHandler = new TestHttpMessageHandler
                {
                    Sender = req =>
                    {
                        return(ReturnJsonResponse(new object()));
                    }
                };
            });
            var properties       = new AuthenticationProperties();
            var correlationKey   = ".AspNet.Correlation.Google";
            var correlationValue = "TestCorrelationId";

            properties.Items.Add(correlationKey, correlationValue);
            properties.RedirectUri = "/me";
            var state       = stateFormat.Protect(properties);
            var transaction = await server.SendAsync(
                "https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.UrlEncode(state),
                correlationKey + "=" + correlationValue);

            Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
            Assert.Contains("error=access_denied", transaction.Response.Headers.Location.ToString());
        }
        public async Task ReplyPathWillRejectIfCodeIsInvalid()
        {
            ISecureDataFormat <AuthenticationProperties> stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("GoogleTest"));
            var server = CreateServer(options =>
            {
                options.ClientId               = "Test Id";
                options.ClientSecret           = "Test Secret";
                options.StateDataFormat        = stateFormat;
                options.BackchannelHttpHandler = new TestHttpMessageHandler
                {
                    Sender = req =>
                    {
                        return(new HttpResponseMessage(HttpStatusCode.BadRequest));
                    }
                };
            });
            var properties       = new AuthenticationProperties();
            var correlationKey   = ".AspNet.Correlation.Google";
            var correlationValue = "TestCorrelationId";

            properties.Dictionary.Add(correlationKey, correlationValue);
            properties.RedirectUri = "/me";
            var state       = stateFormat.Protect(properties);
            var transaction = await SendAsync(server,
                                              "https://example.com/signin-google?code=TestCode&state=" + Uri.EscapeDataString(state),
                                              correlationKey + "=" + correlationValue);

            transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
            transaction.Response.Headers.Location.ToString().ShouldContain("error=access_denied");
        }
        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]);
        }
Пример #4
0
    public async Task ChallengeWillUseAuthenticationPropertiesParametersAsQueryArguments()
    {
        var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider(NullLoggerFactory.Instance).CreateProtector("MicrosoftTest"));

        using var host = await CreateHost(o =>
        {
            o.ClientId        = "Test Id";
            o.ClientSecret    = "Test Secret";
            o.StateDataFormat = stateFormat;
        });

        using var server = host.GetTestServer();
        var transaction = await server.SendAsync("https://example.com/challenge");

        Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);

        // verify query arguments
        var query = QueryHelpers.ParseQuery(transaction.Response.Headers.Location.Query);

        Assert.Equal("https://graph.microsoft.com/user.read", query["scope"]);
        Assert.Equal("consumers", query["domain_hint"]);
        Assert.Equal("username", query["login_hint"]);
        Assert.Equal("select_account", query["prompt"]);
        Assert.Equal("query", query["response_mode"]);

        // verify that the passed items were not serialized
        var stateProperties = stateFormat.Unprotect(query["state"]);

        Assert.DoesNotContain("scope", stateProperties.Items.Keys);
        Assert.DoesNotContain("domain_hint", stateProperties.Items.Keys);
        Assert.DoesNotContain("login_hint", stateProperties.Items.Keys);
        Assert.DoesNotContain("prompt", stateProperties.Items.Keys);
        Assert.DoesNotContain("response_mode", stateProperties.Items.Keys);
    }
Пример #5
0
        public async Task SignOutWith_Specific_RedirectUri_From_Authentication_Properites()
        {
            var configuration = TestServerBuilder.CreateDefaultOpenIdConnectConfiguration();
            var stateFormat   = new PropertiesDataFormat(new EphemeralDataProtectionProvider(NullLoggerFactory.Instance).CreateProtector("OIDCTest"));
            var server        = TestServerBuilder.CreateServer(o =>
            {
                o.Authority            = TestServerBuilder.DefaultAuthority;
                o.StateDataFormat      = stateFormat;
                o.ClientId             = "Test Id";
                o.Configuration        = configuration;
                o.SignedOutRedirectUri = "https://example.com/postlogout";
            });

            var transaction = await server.SendAsync("https://example.com/signout_with_specific_redirect_uri");

            Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);

            var query = transaction.Response.Headers.Location.Query.Substring(1).Split('&')
                        .Select(each => each.Split('='))
                        .ToDictionary(pair => pair[0], pair => pair[1]);

            string redirectUri;

            Assert.True(query.TryGetValue("post_logout_redirect_uri", out redirectUri));
            Assert.Equal(UrlEncoder.Default.Encode("https://example.com/signout-callback-oidc"), redirectUri, true);

            string state;

            Assert.True(query.TryGetValue("state", out state));
            var properties = stateFormat.Unprotect(state);

            Assert.Equal("http://www.example.com/specific_redirect_uri", properties.RedirectUri, true);
        }
Пример #6
0
        public DiscourseAuthenticationOptions()
        {
            CallbackPath = "/auth-discourse";

            _nonceCookieBuilder = new DiscourseNonceCookieBuilder(this)
            {
                Name         = ".CitizenFX.Discourse.Nonce.",
                HttpOnly     = true,
                SameSite     = SameSiteMode.None,
                SecurePolicy = CookieSecurePolicy.SameAsRequest,
                IsEssential  = true,
            };

            DataProtectionProvider = Microsoft.AspNetCore.DataProtection.DataProtectionProvider.Create("FXServer");

            var dataProtector = DataProtectionProvider.CreateProtector(
                typeof(DiscourseAuthenticationHandler).FullName,
                typeof(string).FullName,
                "DAO",
                "v1");

            StringDataFormat = new SecureDataFormat <string>(new StringSerializer(), dataProtector);

            StateDataFormat = new PropertiesDataFormat(dataProtector);
        }
Пример #7
0
        public async Task CanRedirectOnError()
        {
            var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("GoogleTest"));
            var server      = CreateServer(options =>
            {
                options.ClientId     = "Test Id";
                options.ClientSecret = "Test Secret";
                options.Events       = new OAuthEvents()
                {
                    OnRemoteError = ctx =>
                    {
                        ctx.Response.Redirect("/error?ErrorMessage=" + UrlEncoder.Default.UrlEncode(ctx.Error.Message));
                        ctx.HandleResponse();
                        return(Task.FromResult(0));
                    }
                };
            });

            //Post a message to the Google middleware
            var transaction = await server.SendAsync(
                "https://example.com/signin-google?code=TestCode");

            Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
            Assert.Equal("/error?ErrorMessage=" + UrlEncoder.Default.UrlEncode("The oauth state was missing or invalid."),
                         transaction.Response.Headers.GetValues("Location").First());
        }
Пример #8
0
        public static AuthenticationProperties GetByCorrelationId(PropertiesDataFormat stateFormat, IList <string> cookies, string correlationId, string schemeName, string correlationCookieName = ".AspNetCore.Correlation")
        {
            var state           = correlationId;
            var fullCookieValue = cookies.FirstOrDefault(x => x.StartsWith($"{correlationCookieName}.{schemeName}.{CorrelationMarker}.{state}"));
            var cookieValue     = GetCookieValue(fullCookieValue, state);
            var stateProperties = stateFormat.Unprotect(cookieValue);

            return(stateProperties);
        }
Пример #9
0
        public void ShorterStateTest(bool expected, string correlationId)
        {
            var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider(NullLoggerFactory.Instance).CreateProtector("WeixinAuthTest"));
            var properties  = new AuthenticationProperties();

            properties.Items[".xrsf"] = correlationId;
            var state = stateFormat.Protect(properties);

            Assert.Equal(expected, state.Length <= 128);
        }
Пример #10
0
        public async Task ReplyPathWillThrowIfCodeIsInvalid(bool redirect)
        {
            var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("GoogleTest"));
            var server      = CreateServer(options =>
            {
                options.ClientId               = "Test Id";
                options.ClientSecret           = "Test Secret";
                options.StateDataFormat        = stateFormat;
                options.BackchannelHttpHandler = new TestHttpMessageHandler
                {
                    Sender = req =>
                    {
                        return(new HttpResponseMessage(HttpStatusCode.BadRequest));
                    }
                };
                if (redirect)
                {
                    options.Events = new OAuthEvents()
                    {
                        OnRemoteError = ctx =>
                        {
                            ctx.Response.Redirect("/error?ErrorMessage=" + UrlEncoder.Default.UrlEncode(ctx.Error.Message));
                            ctx.HandleResponse();
                            return(Task.FromResult(0));
                        }
                    };
                }
            });
            var properties       = new AuthenticationProperties();
            var correlationKey   = ".AspNet.Correlation.Google";
            var correlationValue = "TestCorrelationId";

            properties.Items.Add(correlationKey, correlationValue);
            properties.RedirectUri = "/me";

            var state = stateFormat.Protect(properties);

            await Assert.ThrowsAsync <HttpRequestException>(() => server.SendAsync(
                                                                "https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.UrlEncode(state),
                                                                correlationKey + "=" + correlationValue));

            //var transaction = await server.SendAsync(
            //    "https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.UrlEncode(state),
            //    correlationKey + "=" + correlationValue);
            //if (redirect)
            //{
            //    Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
            //    Assert.Equal("/error?ErrorMessage=" + UrlEncoder.Default.UrlEncode("Access token was not found."),
            //        transaction.Response.Headers.GetValues("Location").First());
            //}
            //else
            //{
            //    Assert.Equal(HttpStatusCode.InternalServerError, transaction.Response.StatusCode);
            //}
        }
        public async Task ReplyPathWillThrowIfCodeIsInvalid(bool redirect)
        {
            var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("GoogleTest"));
            var server      = CreateServer(new GoogleOptions
            {
                ClientId               = "Test Id",
                ClientSecret           = "Test Secret",
                StateDataFormat        = stateFormat,
                BackchannelHttpHandler = new TestHttpMessageHandler
                {
                    Sender = req =>
                    {
                        return(ReturnJsonResponse(new { Error = "Error" },
                                                  HttpStatusCode.BadRequest));
                    }
                },
                Events = redirect ? new OAuthEvents()
                {
                    OnRemoteFailure = ctx =>
                    {
                        ctx.Response.Redirect("/error?FailureMessage=" + UrlEncoder.Default.Encode(ctx.Failure.Message));
                        ctx.HandleResponse();
                        return(Task.FromResult(0));
                    }
                } : new OAuthEvents()
            });
            var properties       = new AuthenticationProperties();
            var correlationKey   = ".xsrf";
            var correlationValue = "TestCorrelationId";

            properties.Items.Add(correlationKey, correlationValue);
            properties.RedirectUri = "/me";

            var state    = stateFormat.Protect(properties);
            var sendTask = server.SendAsync(
                "https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.Encode(state),
                $".AspNetCore.Correlation.Google.{correlationValue}=N");

            if (redirect)
            {
                var transaction = await sendTask;
                Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
                Assert.Equal("/error?FailureMessage=" + UrlEncoder.Default.Encode("OAuth token endpoint failure: Status: BadRequest;Headers: ;Body: {\"Error\":\"Error\"};"),
                             transaction.Response.Headers.GetValues("Location").First());
            }
            else
            {
                var error = await Assert.ThrowsAnyAsync <Exception>(() => sendTask);

                Assert.Equal("OAuth token endpoint failure: Status: BadRequest;Headers: ;Body: {\"Error\":\"Error\"};", error.GetBaseException().Message);
            }
        }
Пример #12
0
        public async Task SignOutWithDefaultRedirectUri()
        {
            ISecureDataFormat <AuthenticationProperties> stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("GoogleTest"));
            var server = CreateServer(options =>
            {
                options.Authority = "https://login.windows.net/common";
                options.ClientId  = "Test Id";
            });

            var transaction = await SendAsync(server, "https://example.com/signout");

            transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
            transaction.Response.Headers.Location.AbsoluteUri.ShouldBe("https://login.windows.net/common/oauth2/logout");
        }
Пример #13
0
        public async Task NoStateCauses500()
        {
            var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("GoogleTest"));
            var server      = CreateServer(options =>
            {
                options.ClientId     = "Test Id";
                options.ClientSecret = "Test Secret";
            });

            //Post a message to the Google middleware
            var transaction = await server.SendAsync(
                "https://example.com/signin-google?code=TestCode");

            Assert.Equal(HttpStatusCode.InternalServerError, transaction.Response.StatusCode);
        }
Пример #14
0
        public void ShorterState_GenerateCorrelationId_Test(bool expected, int len)
        {
            var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider(NullLoggerFactory.Instance).CreateProtector("WeixinAuthTest"));
            var properties  = new AuthenticationProperties();

            var cryptoRandom = RandomNumberGenerator.Create();
            var bytes        = new byte[len];

            cryptoRandom.GetBytes(bytes);
            var correlationId = Base64UrlTextEncoder.Encode(bytes);

            properties.Items[".xrsf"] = correlationId;
            var state = stateFormat.Protect(properties);

            Assert.Equal(expected, state.Length <= 128);
        }
Пример #15
0
        public void ShorterStateTest_WhereKeepRedirect(bool expected, int correlationIdGeneratorSize, int redirectUrlLen)
        {
            var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider(NullLoggerFactory.Instance).CreateProtector("WeixinAuthTest"));
            var properties  = new AuthenticationProperties();

            var cryptoRandom = RandomNumberGenerator.Create();
            var bytes        = new byte[correlationIdGeneratorSize];

            cryptoRandom.GetBytes(bytes);
            var correlationId = Base64UrlTextEncoder.Encode(bytes);

            properties.Items[".xrsf"] = correlationId;

            var redirectUrl = new string('a', redirectUrlLen);

            properties.Items[".redirect"] = redirectUrl;

            var state = stateFormat.Protect(properties);

            Assert.Equal(expected, state.Length <= 128);
        }
        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));
            }
        }
Пример #17
0
        public async Task ChallengeWillUseNotifications()
        {
            ISecureDataFormat <AuthenticationProperties> stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("GoogleTest"));
            var server = CreateServer(options =>
            {
                options.Authority     = "https://login.windows.net/common";
                options.ClientId      = "Test Id";
                options.Notifications = new OpenIdConnectAuthenticationNotifications
                {
                    MessageReceived = notification =>
                    {
                        notification.ProtocolMessage.Scope = "test openid profile";
                        notification.HandleResponse();
                        return(Task.FromResult <object>(null));
                    }
                };
            });

            var properties  = new AuthenticationProperties();
            var state       = stateFormat.Protect(properties);
            var transaction = await SendAsync(server, "https://example.com/challenge");

            transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
        }
Пример #18
0
 public async Task ReplyPathWillRejectIfAccessTokenIsMissing(bool redirect)
 {
     var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("GoogleTest"));
     var server = CreateServer(options =>
     {
         options.ClientId = "Test Id";
         options.ClientSecret = "Test Secret";
         options.StateDataFormat = stateFormat;
         options.BackchannelHttpHandler = new TestHttpMessageHandler
         {
             Sender = req =>
             {
                 return ReturnJsonResponse(new object());
             }
         };
         if (redirect)
         {
             options.Events = new OAuthEvents()
             {
                 OnRemoteError = ctx =>
                 {
                     ctx.Response.Redirect("/error?ErrorMessage=" + UrlEncoder.Default.UrlEncode(ctx.Error.Message));
                     ctx.HandleResponse();
                     return Task.FromResult(0);
                 }
             };
         }
     });
     var properties = new AuthenticationProperties();
     var correlationKey = ".AspNet.Correlation.Google";
     var correlationValue = "TestCorrelationId";
     properties.Items.Add(correlationKey, correlationValue);
     properties.RedirectUri = "/me";
     var state = stateFormat.Protect(properties);
     var transaction = await server.SendAsync(
         "https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.UrlEncode(state),
         correlationKey + "=" + correlationValue);
     if (redirect)
     {
         Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
         Assert.Equal("/error?ErrorMessage=" + UrlEncoder.Default.UrlEncode("Access token was not found."),
             transaction.Response.Headers.GetValues("Location").First());
     }
     else
     {
         Assert.Equal(HttpStatusCode.InternalServerError, transaction.Response.StatusCode);
     }
 }
Пример #19
0
        public async Task NullRedirectUriWillRedirectToSlash()
        {
            var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("GoogleTest"));
            var server = CreateServer(options =>
            {
                options.ClientId = "Test Id";
                options.ClientSecret = "Test Secret";
                options.StateDataFormat = stateFormat;
                options.BackchannelHttpHandler = new TestHttpMessageHandler
                {
                    Sender = req =>
                    {
                        if (req.RequestUri.AbsoluteUri == "https://accounts.google.com/o/oauth2/token")
                        {
                            return ReturnJsonResponse(new
                            {
                                access_token = "Test Access Token",
                                expires_in = 3600,
                                token_type = "Bearer",
                                refresh_token = "Test Refresh Token"
                            });
                        }
                        else if (req.RequestUri.GetComponents(UriComponents.SchemeAndServer | UriComponents.Path, UriFormat.UriEscaped) == "https://www.googleapis.com/plus/v1/people/me")
                        {
                            return ReturnJsonResponse(new
                            {
                                id = "Test User ID",
                                displayName = "Test Name",
                                name = new
                                {
                                    familyName = "Test Family Name",
                                    givenName = "Test Given Name"
                                },
                                url = "Profile link",
                                emails = new[]
                                    {
                                        new
                                        {
                                            value = "Test email",
                                            type = "account"
                                        }
                                    }
                            });
                        }

                        return null;
                    }
                };
                options.Events = new OAuthEvents
                {
                    OnTicketReceived = context =>
                    {
                        context.AuthenticationTicket.Properties.RedirectUri = null;
                        return Task.FromResult(0);
                    }
                };
            });
            var properties = new AuthenticationProperties();
            var correlationKey = ".AspNet.Correlation.Google";
            var correlationValue = "TestCorrelationId";
            properties.Items.Add(correlationKey, correlationValue);
            var state = stateFormat.Protect(properties);
            var transaction = await server.SendAsync(
                "https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.UrlEncode(state),
                correlationKey + "=" + correlationValue);
            Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
            Assert.Equal("/", transaction.Response.Headers.GetValues("Location").First());
            Assert.Equal(2, transaction.SetCookie.Count);
            Assert.Contains(correlationKey, transaction.SetCookie[0]);
            Assert.Contains(".AspNet." + TestExtensions.CookieAuthenticationScheme, transaction.SetCookie[1]);
        }
        public async Task AuthenticatedEventCanGetRefreshToken()
        {
            ISecureDataFormat<AuthenticationProperties> stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("MsftTest"));
            var server = CreateServer(
                options =>
                {
                    options.ClientId = "Test Client Id";
                    options.ClientSecret = "Test Client Secret";
                    options.StateDataFormat = stateFormat;
                    options.BackchannelHttpHandler = new TestHttpMessageHandler
                    {
                        Sender = req =>
                        {
                            if (req.RequestUri.AbsoluteUri == "https://login.live.com/oauth20_token.srf")
                            {
                                return ReturnJsonResponse(new
                                {
                                    access_token = "Test Access Token",
                                    expire_in = 3600,
                                    token_type = "Bearer",
                                    refresh_token = "Test Refresh Token"
                                });
                            }
                            else if (req.RequestUri.GetLeftPart(UriPartial.Path) == "https://apis.live.net/v5.0/me")
                            {
                                return ReturnJsonResponse(new
                                {
                                    id = "Test User ID",
                                    name = "Test Name",
                                    first_name = "Test Given Name",
                                    last_name = "Test Family Name",
                                    emails = new
                                    {
                                        preferred = "Test email"
                                    }
                                });
                            }

                            return null;
                        }
                    };
                    options.Notifications = new MicrosoftAccountAuthenticationNotifications
                    {
                        OnAuthenticated = context =>
                        {
                            var refreshToken = context.RefreshToken;
                            context.Principal.AddIdentity(new ClaimsIdentity(new Claim[] { new Claim("RefreshToken", refreshToken) }));
                            return Task.FromResult<object>(null);
                        }
                    };
                },
                context =>
                {
                    Describe(context.Response, context.User);
                    return true;
                });
            var properties = new AuthenticationProperties();
            var correlationKey = ".AspNet.Correlation.Microsoft";
            var correlationValue = "TestCorrelationId";
            properties.Dictionary.Add(correlationKey, correlationValue);
            properties.RedirectUri = "/me";
            var state = stateFormat.Protect(properties);
            var transaction = await SendAsync(server,
                "https://example.com/signin-microsoft?code=TestCode&state=" + Uri.EscapeDataString(state),
                correlationKey + "=" + correlationValue);
            transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
            transaction.Response.Headers.Location.ToString().ShouldBe("/me");
            transaction.SetCookie.Count.ShouldBe(2);
            transaction.SetCookie[0].ShouldContain(correlationKey);
            transaction.SetCookie[1].ShouldContain(".AspNet.External");

            var authCookie = transaction.AuthenticationCookieValue;
            transaction = await SendAsync(server, "https://example.com/me", authCookie);
            transaction.Response.StatusCode.ShouldBe(HttpStatusCode.OK);
            transaction.FindClaimValue("RefreshToken").ShouldBe("Test Refresh Token");
        }
        public async Task AuthenticatedEventCanGetRefreshToken()
        {
            ISecureDataFormat <AuthenticationProperties> stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("MsftTest"));
            var server = CreateServer(
                options =>
            {
                options.ClientId               = "Test Client Id";
                options.ClientSecret           = "Test Client Secret";
                options.StateDataFormat        = stateFormat;
                options.BackchannelHttpHandler = new TestHttpMessageHandler
                {
                    Sender = req =>
                    {
                        if (req.RequestUri.AbsoluteUri == "https://login.live.com/oauth20_token.srf")
                        {
                            return(ReturnJsonResponse(new
                            {
                                access_token = "Test Access Token",
                                expire_in = 3600,
                                token_type = "Bearer",
                                refresh_token = "Test Refresh Token"
                            }));
                        }
                        else if (req.RequestUri.GetLeftPart(UriPartial.Path) == "https://apis.live.net/v5.0/me")
                        {
                            return(ReturnJsonResponse(new
                            {
                                id = "Test User ID",
                                name = "Test Name",
                                first_name = "Test Given Name",
                                last_name = "Test Family Name",
                                emails = new
                                {
                                    preferred = "Test email"
                                }
                            }));
                        }

                        return(null);
                    }
                };
                options.Notifications = new MicrosoftAccountAuthenticationNotifications
                {
                    OnAuthenticated = context =>
                    {
                        var refreshToken = context.RefreshToken;
                        context.Principal.AddIdentity(new ClaimsIdentity(new Claim[] { new Claim("RefreshToken", refreshToken) }));
                        return(Task.FromResult <object>(null));
                    }
                };
            },
                context =>
            {
                Describe(context.Response, context.User);
                return(true);
            });
            var properties       = new AuthenticationProperties();
            var correlationKey   = ".AspNet.Correlation.Microsoft";
            var correlationValue = "TestCorrelationId";

            properties.Dictionary.Add(correlationKey, correlationValue);
            properties.RedirectUri = "/me";
            var state       = stateFormat.Protect(properties);
            var transaction = await SendAsync(server,
                                              "https://example.com/signin-microsoft?code=TestCode&state=" + Uri.EscapeDataString(state),
                                              correlationKey + "=" + correlationValue);

            transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
            transaction.Response.Headers.Location.ToString().ShouldBe("/me");
            transaction.SetCookie.Count.ShouldBe(2);
            transaction.SetCookie[0].ShouldContain(correlationKey);
            transaction.SetCookie[1].ShouldContain(".AspNet.External");

            var authCookie = transaction.AuthenticationCookieValue;

            transaction = await SendAsync(server, "https://example.com/me", authCookie);

            transaction.Response.StatusCode.ShouldBe(HttpStatusCode.OK);
            transaction.FindClaimValue("RefreshToken").ShouldBe("Test Refresh Token");
        }
Пример #22
0
        public async Task NullRedirectUriWillRedirectToSlash()
        {
            var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("GoogleTest"));
            var server      = CreateServer(options =>
            {
                options.ClientId               = "Test Id";
                options.ClientSecret           = "Test Secret";
                options.StateDataFormat        = stateFormat;
                options.BackchannelHttpHandler = new TestHttpMessageHandler
                {
                    Sender = req =>
                    {
                        if (req.RequestUri.AbsoluteUri == "https://accounts.google.com/o/oauth2/token")
                        {
                            return(ReturnJsonResponse(new
                            {
                                access_token = "Test Access Token",
                                expires_in = 3600,
                                token_type = "Bearer",
                                refresh_token = "Test Refresh Token"
                            }));
                        }
                        else if (req.RequestUri.GetComponents(UriComponents.SchemeAndServer | UriComponents.Path, UriFormat.UriEscaped) == "https://www.googleapis.com/plus/v1/people/me")
                        {
                            return(ReturnJsonResponse(new
                            {
                                id = "Test User ID",
                                displayName = "Test Name",
                                name = new
                                {
                                    familyName = "Test Family Name",
                                    givenName = "Test Given Name"
                                },
                                url = "Profile link",
                                emails = new[]
                                {
                                    new
                                    {
                                        value = "Test email",
                                        type = "account"
                                    }
                                }
                            }));
                        }

                        return(null);
                    }
                };
                options.Events = new OAuthEvents
                {
                    OnTicketReceived = context =>
                    {
                        context.AuthenticationTicket.Properties.RedirectUri = null;
                        return(Task.FromResult(0));
                    }
                };
            });
            var properties       = new AuthenticationProperties();
            var correlationKey   = ".AspNet.Correlation.Google";
            var correlationValue = "TestCorrelationId";

            properties.Items.Add(correlationKey, correlationValue);
            var state       = stateFormat.Protect(properties);
            var transaction = await server.SendAsync(
                "https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.UrlEncode(state),
                correlationKey + "=" + correlationValue);

            Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
            Assert.Equal("/", transaction.Response.Headers.GetValues("Location").First());
            Assert.Equal(2, transaction.SetCookie.Count);
            Assert.Contains(correlationKey, transaction.SetCookie[0]);
            Assert.Contains(".AspNet." + TestExtensions.CookieAuthenticationScheme, transaction.SetCookie[1]);
        }
 public async Task ReplyPathWillRejectIfAccessTokenIsMissing()
 {
     var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("GoogleTest"));
     var server = CreateServer(options =>
     {
         options.ClientId = "Test Id";
         options.ClientSecret = "Test Secret";
         options.StateDataFormat = stateFormat;
         options.BackchannelHttpHandler = new TestHttpMessageHandler
         {
             Sender = req =>
             {
                 return ReturnJsonResponse(new object());
             }
         };
     });
     var properties = new AuthenticationProperties();
     var correlationKey = ".AspNet.Correlation.Google";
     var correlationValue = "TestCorrelationId";
     properties.Items.Add(correlationKey, correlationValue);
     properties.RedirectUri = "/me";
     var state = stateFormat.Protect(properties);
     var transaction = await server.SendAsync(
         "https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.UrlEncode(state),
         correlationKey + "=" + correlationValue);
     Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
     Assert.Contains("error=access_denied", transaction.Response.Headers.Location.ToString());
 }
        public async Task AuthenticatedEventCanGetRefreshToken()
        {
            var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("GoogleTest"));
            var server      = CreateServer(new GoogleOptions
            {
                ClientId               = "Test Id",
                ClientSecret           = "Test Secret",
                StateDataFormat        = stateFormat,
                BackchannelHttpHandler = new TestHttpMessageHandler
                {
                    Sender = req =>
                    {
                        if (req.RequestUri.AbsoluteUri == "https://www.googleapis.com/oauth2/v3/token")
                        {
                            return(ReturnJsonResponse(new
                            {
                                access_token = "Test Access Token",
                                expires_in = 3600,
                                token_type = "Bearer",
                                refresh_token = "Test Refresh Token"
                            }));
                        }
                        else if (req.RequestUri.GetComponents(UriComponents.SchemeAndServer | UriComponents.Path, UriFormat.UriEscaped) == "https://www.googleapis.com/plus/v1/people/me")
                        {
                            return(ReturnJsonResponse(new
                            {
                                id = "Test User ID",
                                displayName = "Test Name",
                                name = new
                                {
                                    familyName = "Test Family Name",
                                    givenName = "Test Given Name"
                                },
                                url = "Profile link",
                                emails = new[]
                                {
                                    new
                                    {
                                        value = "Test email",
                                        type = "account"
                                    }
                                }
                            }));
                        }

                        throw new NotImplementedException(req.RequestUri.AbsoluteUri);
                    }
                },
                Events = new OAuthEvents
                {
                    OnCreatingTicket = context =>
                    {
                        var refreshToken = context.RefreshToken;
                        context.Ticket.Principal.AddIdentity(new ClaimsIdentity(new Claim[] { new Claim("RefreshToken", refreshToken, ClaimValueTypes.String, "Google") }, "Google"));
                        return(Task.FromResult(0));
                    }
                }
            });
            var properties       = new AuthenticationProperties();
            var correlationKey   = ".xsrf";
            var correlationValue = "TestCorrelationId";

            properties.Items.Add(correlationKey, correlationValue);
            properties.RedirectUri = "/me";
            var state       = stateFormat.Protect(properties);
            var transaction = await server.SendAsync(
                "https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.Encode(state),
                $".AspNetCore.Correlation.Google.{correlationValue}=N");

            Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
            Assert.Equal("/me", transaction.Response.Headers.GetValues("Location").First());
            Assert.Equal(2, transaction.SetCookie.Count);
            Assert.Contains($".AspNetCore.Correlation.Google.{correlationValue}", transaction.SetCookie[0]);
            Assert.Contains(".AspNetCore." + TestExtensions.CookieAuthenticationScheme, transaction.SetCookie[1]);

            var authCookie = transaction.AuthenticationCookieValue;

            transaction = await server.SendAsync("https://example.com/me", authCookie);

            Assert.Equal(HttpStatusCode.OK, transaction.Response.StatusCode);
            Assert.Equal("Test Refresh Token", transaction.FindClaimValue("RefreshToken"));
        }
Пример #25
0
        public async Task CanRedirectOnError()
        {
            var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("GoogleTest"));
            var server = CreateServer(options =>
            {
                options.ClientId = "Test Id";
                options.ClientSecret = "Test Secret";
                options.Events = new OAuthEvents()
                {
                    OnRemoteError = ctx =>
                    {
                        ctx.Response.Redirect("/error?ErrorMessage=" + UrlEncoder.Default.UrlEncode(ctx.Error.Message));
                        ctx.HandleResponse();
                        return Task.FromResult(0);
                    }
                };
            });

            //Post a message to the Google middleware
            var transaction = await server.SendAsync(
                "https://example.com/signin-google?code=TestCode");

            Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
            Assert.Equal("/error?ErrorMessage=" + UrlEncoder.Default.UrlEncode("The oauth state was missing or invalid."),
                transaction.Response.Headers.GetValues("Location").First());
        }
Пример #26
0
        public async Task ValidateAuthenticatedContext()
        {
            var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("GoogleTest"));
            var server      = CreateServer(options =>
            {
                options.ClientId        = "Test Id";
                options.ClientSecret    = "Test Secret";
                options.StateDataFormat = stateFormat;
                options.AccessType      = "offline";
                options.Events          = new OAuthEvents()
                {
                    OnCreatingTicket = context =>
                    {
                        Assert.NotNull(context.User);
                        Assert.Equal(context.AccessToken, "Test Access Token");
                        Assert.Equal(context.RefreshToken, "Test Refresh Token");
                        Assert.Equal(context.ExpiresIn, TimeSpan.FromSeconds(3600));
                        Assert.Equal(GoogleHelper.GetEmail(context.User), "Test email");
                        Assert.Equal(GoogleHelper.GetId(context.User), "Test User ID");
                        Assert.Equal(GoogleHelper.GetName(context.User), "Test Name");
                        Assert.Equal(GoogleHelper.GetFamilyName(context.User), "Test Family Name");
                        Assert.Equal(GoogleHelper.GetGivenName(context.User), "Test Given Name");
                        return(Task.FromResult(0));
                    }
                };
                options.BackchannelHttpHandler = new TestHttpMessageHandler
                {
                    Sender = req =>
                    {
                        if (req.RequestUri.AbsoluteUri == "https://accounts.google.com/o/oauth2/token")
                        {
                            return(ReturnJsonResponse(new
                            {
                                access_token = "Test Access Token",
                                expires_in = 3600,
                                token_type = "Bearer",
                                refresh_token = "Test Refresh Token"
                            }));
                        }
                        else if (req.RequestUri.GetLeftPart(UriPartial.Path) == "https://www.googleapis.com/plus/v1/people/me")
                        {
                            return(ReturnJsonResponse(new
                            {
                                id = "Test User ID",
                                displayName = "Test Name",
                                name = new
                                {
                                    familyName = "Test Family Name",
                                    givenName = "Test Given Name"
                                },
                                url = "Profile link",
                                emails = new[]
                                {
                                    new
                                    {
                                        value = "Test email",
                                        type = "account"
                                    }
                                }
                            }));
                        }

                        return(null);
                    }
                };
            });

            var properties       = new AuthenticationProperties();
            var correlationKey   = ".AspNet.Correlation.Google";
            var correlationValue = "TestCorrelationId";

            properties.Items.Add(correlationKey, correlationValue);
            properties.RedirectUri = "/foo";
            var state = stateFormat.Protect(properties);

            //Post a message to the Google middleware
            var transaction = await server.SendAsync(
                "https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.UrlEncode(state),
                correlationKey + "=" + correlationValue);

            Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
            Assert.Equal("/foo", transaction.Response.Headers.GetValues("Location").First());
        }
 public async Task ReplyPathWillRejectIfCodeIsInvalid()
 {
     ISecureDataFormat<AuthenticationProperties> stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("GoogleTest"));
     var server = CreateServer(options =>
     {
         options.ClientId = "Test Id";
         options.ClientSecret = "Test Secret";
         options.StateDataFormat = stateFormat;
         options.BackchannelHttpHandler = new TestHttpMessageHandler
         {
             Sender = req =>
             {
                 return new HttpResponseMessage(HttpStatusCode.BadRequest);
             }
         };
     });
     var properties = new AuthenticationProperties();
     var correlationKey = ".AspNet.Correlation.Google";
     var correlationValue = "TestCorrelationId";
     properties.Dictionary.Add(correlationKey, correlationValue);
     properties.RedirectUri = "/me";
     var state = stateFormat.Protect(properties);
     var transaction = await SendAsync(server,
         "https://example.com/signin-google?code=TestCode&state=" + Uri.EscapeDataString(state),
         correlationKey + "=" + correlationValue);
     transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
     transaction.Response.Headers.Location.ToString().ShouldContain("error=access_denied");
 }
        public async Task ChallengeWillUseNotifications()
        {
            ISecureDataFormat<AuthenticationProperties> stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("GoogleTest"));
            var server = CreateServer(options =>
            {
                options.Authority = "https://login.windows.net/common";
                options.ClientId = "Test Id";
                options.Notifications = new OpenIdConnectAuthenticationNotifications
                {
                    MessageReceived = notification =>
                        {
                            notification.ProtocolMessage.Scope = "test openid profile";
                            notification.HandleResponse();
                            return Task.FromResult<object>(null);
                        }
                };
            });

            var properties = new AuthenticationProperties();
            var state = stateFormat.Protect(properties);
            var transaction = await SendAsync(server,"https://example.com/challenge");
            transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
        }
        public async Task AuthenticatedEventCanGetRefreshToken()
        {
            ISecureDataFormat<AuthenticationProperties> stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("GoogleTest"));
            var server = CreateServer(options =>
            {
                options.ClientId = "Test Id";
                options.ClientSecret = "Test Secret";
                options.StateDataFormat = stateFormat;
                options.BackchannelHttpHandler = new TestHttpMessageHandler
                {
                    Sender = req =>
                    {
                        if (req.RequestUri.AbsoluteUri == "https://accounts.google.com/o/oauth2/token")
                        {
                            return ReturnJsonResponse(new
                            {
                                access_token = "Test Access Token",
                                expire_in = 3600,
                                token_type = "Bearer",
                                refresh_token = "Test Refresh Token"
                            });
                        }
                        else if (req.RequestUri.GetLeftPart(UriPartial.Path) == "https://www.googleapis.com/plus/v1/people/me")
                        {
                            return ReturnJsonResponse(new
                            {
                                id = "Test User ID",
                                displayName = "Test Name",
                                name = new
                                {
                                    familyName = "Test Family Name",
                                    givenName = "Test Given Name"
                                },
                                url = "Profile link",
                                emails = new[]
                                    {
                                        new
                                        {
                                            value = "Test email",
                                            type = "account"
                                        }
                                    }
                            });
                        }

                        return null;
                    }
                };
                options.Notifications = new GoogleAuthenticationNotifications()
                {
                    OnAuthenticated = context =>
                        {
                            var refreshToken = context.RefreshToken;
                            context.Principal.AddIdentity(new ClaimsIdentity(new Claim[] { new Claim("RefreshToken", refreshToken) }, "Google"));
                            return Task.FromResult<object>(null);
                        }
                };
            });
            var properties = new AuthenticationProperties();
            var correlationKey = ".AspNet.Correlation.Google";
            var correlationValue = "TestCorrelationId";
            properties.Dictionary.Add(correlationKey, correlationValue);
            properties.RedirectUri = "/me";
            var state = stateFormat.Protect(properties);
            var transaction = await SendAsync(server,
                "https://example.com/signin-google?code=TestCode&state=" + Uri.EscapeDataString(state),
                correlationKey + "=" + correlationValue);
            transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
            transaction.Response.Headers.Location.ToString().ShouldBe("/me");
            transaction.SetCookie.Count.ShouldBe(2);
            transaction.SetCookie[0].ShouldContain(correlationKey);
            transaction.SetCookie[1].ShouldContain(".AspNet.Cookie");

            var authCookie = transaction.AuthenticationCookieValue;
            transaction = await SendAsync(server, "https://example.com/me", authCookie);
            transaction.Response.StatusCode.ShouldBe(HttpStatusCode.OK);
            transaction.FindClaimValue("RefreshToken").ShouldBe("Test Refresh Token");
        }
        public async Task ValidateAuthenticatedContext()
        {
            var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("GoogleTest"));
            var server = CreateServer(options =>
            {
                options.ClientId = "Test Id";
                options.ClientSecret = "Test Secret";
                options.StateDataFormat = stateFormat;
                options.AccessType = "offline";
                options.Events = new OAuthEvents()
                {
                    OnCreatingTicket = context =>
                    {
                        Assert.NotNull(context.User);
                        Assert.Equal(context.AccessToken, "Test Access Token");
                        Assert.Equal(context.RefreshToken, "Test Refresh Token");
                        Assert.Equal(context.ExpiresIn, TimeSpan.FromSeconds(3600));
                        Assert.Equal(GoogleHelper.GetEmail(context.User), "Test email");
                        Assert.Equal(GoogleHelper.GetId(context.User), "Test User ID");
                        Assert.Equal(GoogleHelper.GetName(context.User), "Test Name");
                        Assert.Equal(GoogleHelper.GetFamilyName(context.User), "Test Family Name");
                        Assert.Equal(GoogleHelper.GetGivenName(context.User), "Test Given Name");
                        return Task.FromResult(0);
                    }
                };
                options.BackchannelHttpHandler = new TestHttpMessageHandler
                {
                    Sender = req =>
                    {
                        if (req.RequestUri.AbsoluteUri == "https://accounts.google.com/o/oauth2/token")
                        {
                            return ReturnJsonResponse(new
                            {
                                access_token = "Test Access Token",
                                expires_in = 3600,
                                token_type = "Bearer",
                                refresh_token = "Test Refresh Token"
                            });
                        }
                        else if (req.RequestUri.GetLeftPart(UriPartial.Path) == "https://www.googleapis.com/plus/v1/people/me")
                        {
                            return ReturnJsonResponse(new
                            {
                                id = "Test User ID",
                                displayName = "Test Name",
                                name = new
                                {
                                    familyName = "Test Family Name",
                                    givenName = "Test Given Name"
                                },
                                url = "Profile link",
                                emails = new[]
                                    {
                                        new
                                        {
                                            value = "Test email",
                                            type = "account"
                                        }
                                    }
                            });
                        }

                        return null;
                    }
                };
            });

            var properties = new AuthenticationProperties();
            var correlationKey = ".AspNet.Correlation.Google";
            var correlationValue = "TestCorrelationId";
            properties.Items.Add(correlationKey, correlationValue);
            properties.RedirectUri = "/foo";
            var state = stateFormat.Protect(properties);

            //Post a message to the Google middleware
            var transaction = await server.SendAsync(
                "https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.UrlEncode(state),
                correlationKey + "=" + correlationValue);

            Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
            Assert.Equal("/foo", transaction.Response.Headers.GetValues("Location").First());
        }
        public async Task CustomUserInfoEndpointHasValidGraphQuery()
        {
            var customUserInfoEndpoint = "https://graph.facebook.com/me?fields=email,timezone,picture";
            string finalUserInfoEndpoint = string.Empty;
            var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("FacebookTest"));
            var server = CreateServer(
                app =>
                {
                    app.UseFacebookAuthentication(options =>
                    {
                        options.AppId = "Test App Id";
                        options.AppSecret = "Test App Secret";
                        options.StateDataFormat = stateFormat;
                        options.UserInformationEndpoint = customUserInfoEndpoint;
                        options.BackchannelHttpHandler = new TestHttpMessageHandler
                        {
                            Sender = req =>
                            {
                                if (req.RequestUri.GetLeftPart(UriPartial.Path) == FacebookDefaults.TokenEndpoint)
                                {
                                    var res = new HttpResponseMessage(HttpStatusCode.OK);
                                    var tokenResponse = new Dictionary<string, string>
                                    {
                                        { "access_token", "TestAuthToken" },
                                    };
                                    res.Content = new FormUrlEncodedContent(tokenResponse);
                                    return res;
                                }
                                if (req.RequestUri.GetLeftPart(UriPartial.Path) ==
                                    new Uri(customUserInfoEndpoint).GetLeftPart(UriPartial.Path))
                                {
                                    finalUserInfoEndpoint = req.RequestUri.ToString();
                                    var res = new HttpResponseMessage(HttpStatusCode.OK);
                                    var graphResponse = JsonConvert.SerializeObject(new
                                    {
                                        id = "TestProfileId",
                                        name = "TestName"
                                    });
                                    res.Content = new StringContent(graphResponse, Encoding.UTF8);
                                    return res;
                                }
                                return null;
                            }
                        };
                    });
                    app.UseCookieAuthentication();
                },
                services =>
                {
                    services.AddAuthentication();
                }, handler: null);

            var properties = new AuthenticationProperties();
            var correlationKey = ".AspNet.Correlation.Facebook";
            var correlationValue = "TestCorrelationId";
            properties.Items.Add(correlationKey, correlationValue);
            properties.RedirectUri = "/me";
            var state = stateFormat.Protect(properties);
            var transaction = await server.SendAsync(
                "https://example.com/signin-facebook?code=TestCode&state=" + UrlEncoder.Default.UrlEncode(state),
                correlationKey + "=" + correlationValue);
            Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
            Assert.Equal("/me", transaction.Response.Headers.GetValues("Location").First());
            Assert.Equal(1, finalUserInfoEndpoint.Count(c => c == '?'));
            Assert.Contains("fields=email,timezone,picture", finalUserInfoEndpoint);
            Assert.Contains("&access_token=", finalUserInfoEndpoint);
        }
Пример #32
0
        public async Task CustomUserInfoEndpointHasValidGraphQuery()
        {
            var customUserInfoEndpoint = "https://graph.facebook.com/me?fields=email,timezone,picture";
            var finalUserInfoEndpoint  = string.Empty;
            var stateFormat            = new PropertiesDataFormat(new EphemeralDataProtectionProvider(NullLoggerFactory.Instance).CreateProtector("FacebookTest"));

            using var host = await CreateHost(
                      app => app.UseAuthentication(),
                      services =>
            {
                services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
                .AddCookie()
                .AddFacebook(o =>
                {
                    o.AppId                   = "Test App Id";
                    o.AppSecret               = "Test App Secret";
                    o.StateDataFormat         = stateFormat;
                    o.UserInformationEndpoint = customUserInfoEndpoint;
                    o.BackchannelHttpHandler  = new TestHttpMessageHandler
                    {
                        Sender = req =>
                        {
                            if (req.RequestUri.GetComponents(UriComponents.SchemeAndServer | UriComponents.Path, UriFormat.UriEscaped) == FacebookDefaults.TokenEndpoint)
                            {
                                var res           = new HttpResponseMessage(HttpStatusCode.OK);
                                var graphResponse = "{ \"access_token\": \"TestAuthToken\" }";
                                res.Content       = new StringContent(graphResponse, Encoding.UTF8);
                                return(res);
                            }
                            if (req.RequestUri.GetComponents(UriComponents.SchemeAndServer | UriComponents.Path, UriFormat.UriEscaped) ==
                                new Uri(customUserInfoEndpoint).GetComponents(UriComponents.SchemeAndServer | UriComponents.Path, UriFormat.UriEscaped))
                            {
                                finalUserInfoEndpoint = req.RequestUri.ToString();
                                var res           = new HttpResponseMessage(HttpStatusCode.OK);
                                var graphResponse = "{ \"id\": \"TestProfileId\", \"name\": \"TestName\" }";
                                res.Content       = new StringContent(graphResponse, Encoding.UTF8);
                                return(res);
                            }
                            return(null);
                        }
                    };
                });
            },
                      handler : null);

            var properties       = new AuthenticationProperties();
            var correlationKey   = ".xsrf";
            var correlationValue = "TestCorrelationId";

            properties.Items.Add(correlationKey, correlationValue);
            properties.RedirectUri = "/me";
            var state = stateFormat.Protect(properties);

            using var server = host.GetTestServer();
            var transaction = await server.SendAsync(
                "https://example.com/signin-facebook?code=TestCode&state=" + UrlEncoder.Default.Encode(state),
                $".AspNetCore.Correlation.{correlationValue}=N");

            Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
            Assert.Equal("/me", transaction.Response.Headers.GetValues("Location").First());
            Assert.Equal(1, finalUserInfoEndpoint.Count(c => c == '?'));
            Assert.Contains("fields=email,timezone,picture", finalUserInfoEndpoint);
            Assert.Contains("&access_token=", finalUserInfoEndpoint);
            Assert.Contains("&appsecret_proof=b7fb6d5a4510926b4af6fe080497827d791dc45fe6541d88ba77bdf6e8e208c6&", finalUserInfoEndpoint);
        }
        public async Task AuthenticatedEventCanGetRefreshToken()
        {
            var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("MsftTest"));
            var server = CreateServer(
                options =>
                {
                    options.ClientId = "Test Client Id";
                    options.ClientSecret = "Test Client Secret";
                    options.StateDataFormat = stateFormat;
                    options.BackchannelHttpHandler = new TestHttpMessageHandler
                    {
                        Sender = req =>
                        {
                            if (req.RequestUri.AbsoluteUri == "https://login.live.com/oauth20_token.srf")
                            {
                                return ReturnJsonResponse(new
                                {
                                    access_token = "Test Access Token",
                                    expire_in = 3600,
                                    token_type = "Bearer",
                                    refresh_token = "Test Refresh Token"
                                });
                            }
                            else if (req.RequestUri.GetComponents(UriComponents.SchemeAndServer | UriComponents.Path, UriFormat.UriEscaped) == "https://apis.live.net/v5.0/me")
                            {
                                return ReturnJsonResponse(new
                                {
                                    id = "Test User ID",
                                    name = "Test Name",
                                    first_name = "Test Given Name",
                                    last_name = "Test Family Name",
                                    emails = new
                                    {
                                        preferred = "Test email"
                                    }
                                });
                            }

                            return null;
                        }
                    };
                    options.Events = new OAuthEvents
                    {
                        OnCreatingTicket = context =>
                        {
                            var refreshToken = context.RefreshToken;
                            context.Principal.AddIdentity(new ClaimsIdentity(new Claim[] { new Claim("RefreshToken", refreshToken, ClaimValueTypes.String, "Microsoft") }, "Microsoft"));
                            return Task.FromResult<object>(null);
                        }
                    };
                });
            var properties = new AuthenticationProperties();
            var correlationKey = ".AspNet.Correlation.Microsoft";
            var correlationValue = "TestCorrelationId";
            properties.Items.Add(correlationKey, correlationValue);
            properties.RedirectUri = "/me";
            var state = stateFormat.Protect(properties);
            var transaction = await server.SendAsync(
                "https://example.com/signin-microsoft?code=TestCode&state=" + UrlEncoder.Default.UrlEncode(state),
                correlationKey + "=" + correlationValue);
            Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
            Assert.Equal("/me", transaction.Response.Headers.GetValues("Location").First());
            Assert.Equal(2, transaction.SetCookie.Count);
            Assert.Contains(correlationKey, transaction.SetCookie[0]);
            Assert.Contains(".AspNet." + TestExtensions.CookieAuthenticationScheme, transaction.SetCookie[1]);

            var authCookie = transaction.AuthenticationCookieValue;
            transaction = await server.SendAsync("https://example.com/me", authCookie);
            Assert.Equal(HttpStatusCode.OK, transaction.Response.StatusCode);
            Assert.Equal("Test Refresh Token", transaction.FindClaimValue("RefreshToken"));
        }
Пример #34
0
        public async Task NoStateCauses500()
        {
            var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("GoogleTest"));
            var server = CreateServer(options =>
            {
                options.ClientId = "Test Id";
                options.ClientSecret = "Test Secret";
            });

            //Post a message to the Google middleware
            var transaction = await server.SendAsync(
                "https://example.com/signin-google?code=TestCode");

            Assert.Equal(HttpStatusCode.InternalServerError, transaction.Response.StatusCode);
        }
        public async Task ReplyPathWillAuthenticateValidAuthorizeCodeAndState(string claimsIssuer)
        {
            var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("GoogleTest"));
            var server = CreateServer(options =>
            {
                options.ClientId = "Test Id";
                options.ClientSecret = "Test Secret";
                options.StateDataFormat = stateFormat;
                options.ClaimsIssuer = claimsIssuer;
                options.BackchannelHttpHandler = new TestHttpMessageHandler
                {
                    Sender = req =>
                    {
                        if (req.RequestUri.AbsoluteUri == "https://accounts.google.com/o/oauth2/token")
                        {
                            return ReturnJsonResponse(new
                            {
                                access_token = "Test Access Token",
                                expires_in = 3600,
                                token_type = "Bearer"
                            });
                        }
                        else if (req.RequestUri.GetLeftPart(UriPartial.Path) == "https://www.googleapis.com/plus/v1/people/me")
                        {
                            return ReturnJsonResponse(new
                            {
                                id = "Test User ID",
                                displayName = "Test Name",
                                name = new
                                {
                                    familyName = "Test Family Name",
                                    givenName = "Test Given Name"
                                },
                                url = "Profile link",
                                emails = new[]
                                {
                                    new
                                    {
                                        value = "Test email",
                                        type = "account"
                                    }
                                }
                            });
                        }

                        return null;
                    }
                };
            });
            var properties = new AuthenticationProperties();
            var correlationKey = ".AspNet.Correlation.Google";
            var correlationValue = "TestCorrelationId";
            properties.Items.Add(correlationKey, correlationValue);
            properties.RedirectUri = "/me";
            var state = stateFormat.Protect(properties);
            var transaction = await server.SendAsync(
                "https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.UrlEncode(state),
                correlationKey + "=" + correlationValue);
            Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
            Assert.Equal("/me", transaction.Response.Headers.GetValues("Location").First());
            Assert.Equal(2, transaction.SetCookie.Count);
            Assert.Contains(correlationKey, transaction.SetCookie[0]);
            Assert.Contains(".AspNet." + TestExtensions.CookieAuthenticationScheme, transaction.SetCookie[1]);

            var authCookie = transaction.AuthenticationCookieValue;
            transaction = await server.SendAsync("https://example.com/me", authCookie);
            Assert.Equal(HttpStatusCode.OK, transaction.Response.StatusCode);
            var expectedIssuer = claimsIssuer ?? GoogleDefaults.AuthenticationScheme;
            Assert.Equal("Test Name", transaction.FindClaimValue(ClaimTypes.Name, expectedIssuer));
            Assert.Equal("Test User ID", transaction.FindClaimValue(ClaimTypes.NameIdentifier, expectedIssuer));
            Assert.Equal("Test Given Name", transaction.FindClaimValue(ClaimTypes.GivenName, expectedIssuer));
            Assert.Equal("Test Family Name", transaction.FindClaimValue(ClaimTypes.Surname, expectedIssuer));
            Assert.Equal("Test email", transaction.FindClaimValue(ClaimTypes.Email, expectedIssuer));

            // Ensure claims transformation 
            Assert.Equal("yup", transaction.FindClaimValue("xform"));
        }
        public async Task AuthenticatedEventCanGetRefreshToken()
        {
            var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("MsftTest"));
            var server      = CreateServer(
                options =>
            {
                options.ClientId               = "Test Client Id";
                options.ClientSecret           = "Test Client Secret";
                options.StateDataFormat        = stateFormat;
                options.BackchannelHttpHandler = new TestHttpMessageHandler
                {
                    Sender = req =>
                    {
                        if (req.RequestUri.AbsoluteUri == "https://login.live.com/oauth20_token.srf")
                        {
                            return(ReturnJsonResponse(new
                            {
                                access_token = "Test Access Token",
                                expire_in = 3600,
                                token_type = "Bearer",
                                refresh_token = "Test Refresh Token"
                            }));
                        }
                        else if (req.RequestUri.GetLeftPart(UriPartial.Path) == "https://apis.live.net/v5.0/me")
                        {
                            return(ReturnJsonResponse(new
                            {
                                id = "Test User ID",
                                name = "Test Name",
                                first_name = "Test Given Name",
                                last_name = "Test Family Name",
                                emails = new
                                {
                                    preferred = "Test email"
                                }
                            }));
                        }

                        return(null);
                    }
                };
                options.Events = new OAuthEvents
                {
                    OnCreatingTicket = context =>
                    {
                        var refreshToken = context.RefreshToken;
                        context.Principal.AddIdentity(new ClaimsIdentity(new Claim[] { new Claim("RefreshToken", refreshToken, ClaimValueTypes.String, "Microsoft") }, "Microsoft"));
                        return(Task.FromResult <object>(null));
                    }
                };
            });
            var properties       = new AuthenticationProperties();
            var correlationKey   = ".AspNet.Correlation.Microsoft";
            var correlationValue = "TestCorrelationId";

            properties.Items.Add(correlationKey, correlationValue);
            properties.RedirectUri = "/me";
            var state       = stateFormat.Protect(properties);
            var transaction = await server.SendAsync(
                "https://example.com/signin-microsoft?code=TestCode&state=" + UrlEncoder.Default.UrlEncode(state),
                correlationKey + "=" + correlationValue);

            Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
            Assert.Equal("/me", transaction.Response.Headers.GetValues("Location").First());
            Assert.Equal(2, transaction.SetCookie.Count);
            Assert.Contains(correlationKey, transaction.SetCookie[0]);
            Assert.Contains(".AspNet." + TestExtensions.CookieAuthenticationScheme, transaction.SetCookie[1]);

            var authCookie = transaction.AuthenticationCookieValue;

            transaction = await server.SendAsync("https://example.com/me", authCookie);

            Assert.Equal(HttpStatusCode.OK, transaction.Response.StatusCode);
            Assert.Equal("Test Refresh Token", transaction.FindClaimValue("RefreshToken"));
        }
        public async Task AuthenticatedEventCanGetRefreshToken()
        {
            var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("GoogleTest"));
            var server = CreateServer(options =>
            {
                options.ClientId = "Test Id";
                options.ClientSecret = "Test Secret";
                options.StateDataFormat = stateFormat;
                options.BackchannelHttpHandler = new TestHttpMessageHandler
                {
                    Sender = req =>
                    {
                        if (req.RequestUri.AbsoluteUri == "https://accounts.google.com/o/oauth2/token")
                        {
                            return ReturnJsonResponse(new
                            {
                                access_token = "Test Access Token",
                                expires_in = 3600,
                                token_type = "Bearer",
                                refresh_token = "Test Refresh Token"
                            });
                        }
                        else if (req.RequestUri.GetLeftPart(UriPartial.Path) == "https://www.googleapis.com/plus/v1/people/me")
                        {
                            return ReturnJsonResponse(new
                            {
                                id = "Test User ID",
                                displayName = "Test Name",
                                name = new
                                {
                                    familyName = "Test Family Name",
                                    givenName = "Test Given Name"
                                },
                                url = "Profile link",
                                emails = new[]
                                    {
                                        new
                                        {
                                            value = "Test email",
                                            type = "account"
                                        }
                                    }
                            });
                        }

                        return null;
                    }
                };
                options.Events = new OAuthEvents
                {
                    OnCreatingTicket = context =>
                    {
                        var refreshToken = context.RefreshToken;
                        context.Principal.AddIdentity(new ClaimsIdentity(new Claim[] { new Claim("RefreshToken", refreshToken, ClaimValueTypes.String, "Google") }, "Google"));
                        return Task.FromResult<object>(null);
                    }
                };
            });
            var properties = new AuthenticationProperties();
            var correlationKey = ".AspNet.Correlation.Google";
            var correlationValue = "TestCorrelationId";
            properties.Items.Add(correlationKey, correlationValue);
            properties.RedirectUri = "/me";
            var state = stateFormat.Protect(properties);
            var transaction = await server.SendAsync(
                "https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.UrlEncode(state),
                correlationKey + "=" + correlationValue);
            Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
            Assert.Equal("/me", transaction.Response.Headers.GetValues("Location").First());
            Assert.Equal(2, transaction.SetCookie.Count);
            Assert.Contains(correlationKey, transaction.SetCookie[0]);
            Assert.Contains(".AspNet." + TestExtensions.CookieAuthenticationScheme, transaction.SetCookie[1]);

            var authCookie = transaction.AuthenticationCookieValue;
            transaction = await server.SendAsync("https://example.com/me", authCookie);
            Assert.Equal(HttpStatusCode.OK, transaction.Response.StatusCode);
            Assert.Equal("Test Refresh Token", transaction.FindClaimValue("RefreshToken"));
        }
Пример #38
0
        public async Task AuthenticatedEventCanGetRefreshToken()
        {
            ISecureDataFormat <AuthenticationProperties> stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("GoogleTest"));
            var server = CreateServer(options =>
            {
                options.ClientId               = "Test Id";
                options.ClientSecret           = "Test Secret";
                options.StateDataFormat        = stateFormat;
                options.BackchannelHttpHandler = new TestHttpMessageHandler
                {
                    Sender = req =>
                    {
                        if (req.RequestUri.AbsoluteUri == "https://accounts.google.com/o/oauth2/token")
                        {
                            return(ReturnJsonResponse(new
                            {
                                access_token = "Test Access Token",
                                expire_in = 3600,
                                token_type = "Bearer",
                                refresh_token = "Test Refresh Token"
                            }));
                        }
                        else if (req.RequestUri.GetLeftPart(UriPartial.Path) == "https://www.googleapis.com/plus/v1/people/me")
                        {
                            return(ReturnJsonResponse(new
                            {
                                id = "Test User ID",
                                displayName = "Test Name",
                                name = new
                                {
                                    familyName = "Test Family Name",
                                    givenName = "Test Given Name"
                                },
                                url = "Profile link",
                                emails = new[]
                                {
                                    new
                                    {
                                        value = "Test email",
                                        type = "account"
                                    }
                                }
                            }));
                        }

                        return(null);
                    }
                };
                options.Notifications = new GoogleAuthenticationNotifications()
                {
                    OnAuthenticated = context =>
                    {
                        var refreshToken = context.RefreshToken;
                        context.Identity.AddClaim(new Claim("RefreshToken", refreshToken));
                        return(Task.FromResult <object>(null));
                    }
                };
            });
            var properties       = new AuthenticationProperties();
            var correlationKey   = ".AspNet.Correlation.Google";
            var correlationValue = "TestCorrelationId";

            properties.Dictionary.Add(correlationKey, correlationValue);
            properties.RedirectUri = "/me";
            var state       = stateFormat.Protect(properties);
            var transaction = await SendAsync(server,
                                              "https://example.com/signin-google?code=TestCode&state=" + Uri.EscapeDataString(state),
                                              correlationKey + "=" + correlationValue);

            transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
            transaction.Response.Headers.Location.ToString().ShouldBe("/me");
            transaction.SetCookie.Count.ShouldBe(2);
            transaction.SetCookie[0].ShouldContain(correlationKey);
            transaction.SetCookie[1].ShouldContain(".AspNet.Cookie");

            var authCookie = transaction.AuthenticationCookieValue;

            transaction = await SendAsync(server, "https://example.com/me", authCookie);

            transaction.Response.StatusCode.ShouldBe(HttpStatusCode.OK);
            transaction.FindClaimValue("RefreshToken").ShouldBe("Test Refresh Token");
        }
Пример #39
0
        public async Task AuthenticatedEventCanGetRefreshToken()
        {
            var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider(NullLoggerFactory.Instance).CreateProtector("MsftTest"));
            var server      = CreateServer(o =>
            {
                o.ClientId               = "Test Client Id";
                o.ClientSecret           = "Test Client Secret";
                o.StateDataFormat        = stateFormat;
                o.BackchannelHttpHandler = new TestHttpMessageHandler
                {
                    Sender = req =>
                    {
                        if (req.RequestUri.AbsoluteUri == "https://login.microsoftonline.com/common/oauth2/v2.0/token")
                        {
                            return(ReturnJsonResponse(new
                            {
                                access_token = "Test Access Token",
                                expire_in = 3600,
                                token_type = "Bearer",
                                refresh_token = "Test Refresh Token"
                            }));
                        }
                        else if (req.RequestUri.GetComponents(UriComponents.SchemeAndServer | UriComponents.Path, UriFormat.UriEscaped) == "https://graph.microsoft.com/v1.0/me")
                        {
                            return(ReturnJsonResponse(new
                            {
                                id = "Test User ID",
                                displayName = "Test Name",
                                givenName = "Test Given Name",
                                surname = "Test Family Name",
                                mail = "Test email"
                            }));
                        }

                        return(null);
                    }
                };
                o.Events = new OAuthEvents
                {
                    OnCreatingTicket = context =>
                    {
                        var refreshToken = context.RefreshToken;
                        context.Principal.AddIdentity(new ClaimsIdentity(new Claim[] { new Claim("RefreshToken", refreshToken, ClaimValueTypes.String, "Microsoft") }, "Microsoft"));
                        return(Task.FromResult <object>(null));
                    }
                };
            });
            var properties       = new AuthenticationProperties();
            var correlationKey   = ".xsrf";
            var correlationValue = "TestCorrelationId";

            properties.Items.Add(correlationKey, correlationValue);
            properties.RedirectUri = "/me";
            var state       = stateFormat.Protect(properties);
            var transaction = await server.SendAsync(
                "https://example.com/signin-microsoft?code=TestCode&state=" + UrlEncoder.Default.Encode(state),
                $".AspNetCore.Correlation.Microsoft.{correlationValue}=N");

            Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
            Assert.Equal("/me", transaction.Response.Headers.GetValues("Location").First());
            Assert.Equal(2, transaction.SetCookie.Count);
            Assert.Contains($".AspNetCore.Correlation.Microsoft.{correlationValue}", transaction.SetCookie[0]);
            Assert.Contains(".AspNetCore." + TestExtensions.CookieAuthenticationScheme, transaction.SetCookie[1]);

            var authCookie = transaction.AuthenticationCookieValue;

            transaction = await server.SendAsync("https://example.com/me", authCookie);

            Assert.Equal(HttpStatusCode.OK, transaction.Response.StatusCode);
            Assert.Equal("Test Refresh Token", transaction.FindClaimValue("RefreshToken"));
        }
        public async Task CustomUserInfoEndpointHasValidGraphQuery()
        {
            var customUserInfoEndpoint = "https://graph.facebook.com/me?fields=email,timezone,picture";
            var finalUserInfoEndpoint  = string.Empty;
            var stateFormat            = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("FacebookTest"));
            var server = CreateServer(
                app =>
            {
                app.UseCookieAuthentication();
                app.UseFacebookAuthentication(new FacebookOptions
                {
                    AppId                   = "Test App Id",
                    AppSecret               = "Test App Secret",
                    StateDataFormat         = stateFormat,
                    UserInformationEndpoint = customUserInfoEndpoint,
                    BackchannelHttpHandler  = new TestHttpMessageHandler
                    {
                        Sender = req =>
                        {
                            if (req.RequestUri.GetComponents(UriComponents.SchemeAndServer | UriComponents.Path, UriFormat.UriEscaped) == FacebookDefaults.TokenEndpoint)
                            {
                                var res           = new HttpResponseMessage(HttpStatusCode.OK);
                                var graphResponse = JsonConvert.SerializeObject(new
                                {
                                    access_token = "TestAuthToken"
                                });
                                res.Content = new StringContent(graphResponse, Encoding.UTF8);
                                return(res);
                            }
                            if (req.RequestUri.GetComponents(UriComponents.SchemeAndServer | UriComponents.Path, UriFormat.UriEscaped) ==
                                new Uri(customUserInfoEndpoint).GetComponents(UriComponents.SchemeAndServer | UriComponents.Path, UriFormat.UriEscaped))
                            {
                                finalUserInfoEndpoint = req.RequestUri.ToString();
                                var res           = new HttpResponseMessage(HttpStatusCode.OK);
                                var graphResponse = JsonConvert.SerializeObject(new
                                {
                                    id   = "TestProfileId",
                                    name = "TestName"
                                });
                                res.Content = new StringContent(graphResponse, Encoding.UTF8);
                                return(res);
                            }
                            return(null);
                        }
                    }
                });
            },
                services =>
            {
                services.AddAuthentication(options => options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme);
            }, handler: null);

            var properties       = new AuthenticationProperties();
            var correlationKey   = ".xsrf";
            var correlationValue = "TestCorrelationId";

            properties.Items.Add(correlationKey, correlationValue);
            properties.RedirectUri = "/me";
            var state       = stateFormat.Protect(properties);
            var transaction = await server.SendAsync(
                "https://example.com/signin-facebook?code=TestCode&state=" + UrlEncoder.Default.Encode(state),
                $".AspNetCore.Correlation.Facebook.{correlationValue}=N");

            Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
            Assert.Equal("/me", transaction.Response.Headers.GetValues("Location").First());
            Assert.Equal(1, finalUserInfoEndpoint.Count(c => c == '?'));
            Assert.Contains("fields=email,timezone,picture", finalUserInfoEndpoint);
            Assert.Contains("&access_token=", finalUserInfoEndpoint);
        }
Пример #41
0
        public async Task ReplyPathWillAuthenticateValidAuthorizeCodeAndState(string claimsIssuer)
        {
            var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("GoogleTest"));
            var server      = CreateServer(options =>
            {
                options.ClientId               = "Test Id";
                options.ClientSecret           = "Test Secret";
                options.StateDataFormat        = stateFormat;
                options.ClaimsIssuer           = claimsIssuer;
                options.BackchannelHttpHandler = new TestHttpMessageHandler
                {
                    Sender = req =>
                    {
                        if (req.RequestUri.AbsoluteUri == "https://accounts.google.com/o/oauth2/token")
                        {
                            return(ReturnJsonResponse(new
                            {
                                access_token = "Test Access Token",
                                expires_in = 3600,
                                token_type = "Bearer"
                            }));
                        }
                        else if (req.RequestUri.GetLeftPart(UriPartial.Path) == "https://www.googleapis.com/plus/v1/people/me")
                        {
                            return(ReturnJsonResponse(new
                            {
                                id = "Test User ID",
                                displayName = "Test Name",
                                name = new
                                {
                                    familyName = "Test Family Name",
                                    givenName = "Test Given Name"
                                },
                                url = "Profile link",
                                emails = new[]
                                {
                                    new
                                    {
                                        value = "Test email",
                                        type = "account"
                                    }
                                }
                            }));
                        }

                        return(null);
                    }
                };
            });
            var properties       = new AuthenticationProperties();
            var correlationKey   = ".AspNet.Correlation.Google";
            var correlationValue = "TestCorrelationId";

            properties.Items.Add(correlationKey, correlationValue);
            properties.RedirectUri = "/me";
            var state       = stateFormat.Protect(properties);
            var transaction = await server.SendAsync(
                "https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.UrlEncode(state),
                correlationKey + "=" + correlationValue);

            Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
            Assert.Equal("/me", transaction.Response.Headers.GetValues("Location").First());
            Assert.Equal(2, transaction.SetCookie.Count);
            Assert.Contains(correlationKey, transaction.SetCookie[0]);
            Assert.Contains(".AspNet." + TestExtensions.CookieAuthenticationScheme, transaction.SetCookie[1]);

            var authCookie = transaction.AuthenticationCookieValue;

            transaction = await server.SendAsync("https://example.com/me", authCookie);

            Assert.Equal(HttpStatusCode.OK, transaction.Response.StatusCode);
            var expectedIssuer = claimsIssuer ?? GoogleDefaults.AuthenticationScheme;

            Assert.Equal("Test Name", transaction.FindClaimValue(ClaimTypes.Name, expectedIssuer));
            Assert.Equal("Test User ID", transaction.FindClaimValue(ClaimTypes.NameIdentifier, expectedIssuer));
            Assert.Equal("Test Given Name", transaction.FindClaimValue(ClaimTypes.GivenName, expectedIssuer));
            Assert.Equal("Test Family Name", transaction.FindClaimValue(ClaimTypes.Surname, expectedIssuer));
            Assert.Equal("Test email", transaction.FindClaimValue(ClaimTypes.Email, expectedIssuer));

            // Ensure claims transformation
            Assert.Equal("yup", transaction.FindClaimValue("xform"));
        }
Пример #42
0
 public async Task ReplyPathWillRejectIfAccessTokenIsMissing(bool redirect)
 {
     var stateFormat = new PropertiesDataFormat(new EphemeralDataProtectionProvider().CreateProtector("GoogleTest"));
     var server = CreateServer(new GoogleOptions
     {
         ClientId = "Test Id",
         ClientSecret = "Test Secret",
         StateDataFormat = stateFormat,
         BackchannelHttpHandler = new TestHttpMessageHandler
         {
             Sender = req =>
             {
                 return ReturnJsonResponse(new object());
             }
         },
         Events = redirect ? new OAuthEvents()
         {
             OnRemoteFailure = ctx =>
             {
                 ctx.Response.Redirect("/error?FailureMessage=" + UrlEncoder.Default.Encode(ctx.Failure.Message));
                 ctx.HandleResponse();
                 return Task.FromResult(0);
             }
         } : new OAuthEvents()
     });
     var properties = new AuthenticationProperties();
     var correlationKey = ".xsrf";
     var correlationValue = "TestCorrelationId";
     properties.Items.Add(correlationKey, correlationValue);
     properties.RedirectUri = "/me";
     var state = stateFormat.Protect(properties);
     var sendTask = server.SendAsync(
         "https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.Encode(state),
         $".AspNetCore.Correlation.Google.{correlationValue}=N");
     if (redirect)
     {
         var transaction = await sendTask;
         Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
         Assert.Equal("/error?FailureMessage=" + UrlEncoder.Default.Encode("Failed to retrieve access token."),
             transaction.Response.Headers.GetValues("Location").First());
     }
     else
     {
         var error = await Assert.ThrowsAnyAsync<Exception>(() => sendTask);
         Assert.Equal("Failed to retrieve access token.", error.GetBaseException().Message);
     }
 }