Example #1
0
        public async Task CodeCanBeUsedOnlyOneTime()
        {
            var server = new OAuth2TestServer(s =>
            {
                s.Options.AuthorizationCodeExpireTimeSpan = TimeSpan.FromMinutes(8);
                s.Options.AccessTokenExpireTimeSpan       = TimeSpan.FromSeconds(655321);
                s.OnAuthorizeEndpoint = SignInEpsilon;
            });

            OAuth2TestServer.Transaction transaction = await server.SendAsync("https://example.com/authorize?client_id=alpha&response_type=code");

            NameValueCollection query = transaction.ParseRedirectQueryString();

            OAuth2TestServer.Transaction transaction2 = await server.SendAsync("https://example.com/token",
                                                                               authenticateHeader : new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes("alpha:beta"))),
                                                                               postBody : "grant_type=authorization_code&code=" + query["code"] + "&client_id=alpha");

            transaction2.ResponseToken["access_token"].Value <string>().ShouldNotBe(null);
            transaction2.ResponseToken["token_type"].Value <string>().ShouldBe("bearer");
            transaction2.ResponseToken["expires_in"].Value <long>().ShouldBe(655321);

            OAuth2TestServer.Transaction transaction3 = await server.SendAsync("https://example.com/token",
                                                                               authenticateHeader : new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes("alpha:beta"))),
                                                                               postBody : "grant_type=authorization_code&code=" + query["code"] + "&client_id=alpha");

            transaction3.ResponseToken["error"].Value <string>().ShouldBe("invalid_grant");
        }
Example #2
0
        public async Task CodeFlowFailsWhenConfidentialClientDoesNotProvideCredentials()
        {
            var server = new OAuth2TestServer(s => { s.OnAuthorizeEndpoint = SignInEpsilon; });

            OAuth2TestServer.Transaction transaction = await server.SendAsync("https://example.com/authorize?client_id=alpha&response_type=code");

            NameValueCollection query = transaction.ParseRedirectQueryString();

            OAuth2TestServer.Transaction transaction2 = await server.SendAsync("https://example.com/token",
                                                                               postBody : "grant_type=authorization_code&code=" + query["code"] + "&client_id=alpha");

            transaction2.Response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
            transaction2.ResponseToken["error"].Value <string>().ShouldBe("invalid_client");
        }
        public async Task AccessTokenMayBeUsed()
        {
            var server = new OAuth2TestServer(s => { s.OnAuthorizeEndpoint = SignInEpsilon; });

            OAuth2TestServer.Transaction transaction1 = await server.SendAsync("https://example.com/authorize?response_type=token&client_id=alpha&redirect_uri=" + Uri.EscapeDataString("https://gamma.com/return"));

            NameValueCollection fragment = transaction1.ParseRedirectFragment();
            string accessToken           = fragment.Get("access_token");

            OAuth2TestServer.Transaction transaction2 = await server.SendAsync("https://example.com/me",
                                                                               authenticateHeader : new AuthenticationHeaderValue("Bearer", accessToken));

            transaction2.Response.StatusCode.ShouldBe(HttpStatusCode.OK);
            transaction2.ResponseText.ShouldBe("epsilon");
        }
Example #4
0
        public async Task CodeFlowRedirectUriMustMatch()
        {
            var server = new OAuth2TestServer(s => { s.OnAuthorizeEndpoint = SignInEpsilon; });

            OAuth2TestServer.Transaction transaction = await server.SendAsync("https://example.com/authorize?client_id=alpha&response_type=code&redirect_uri=" + Uri.EscapeDataString("https://gamma.com/return"));

            NameValueCollection query = transaction.ParseRedirectQueryString();

            OAuth2TestServer.Transaction transaction2 = await server.SendAsync("https://example.com/token",
                                                                               authenticateHeader : new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes("alpha:beta"))),
                                                                               postBody : "grant_type=authorization_code&code=" + query["code"] + "&client_id=alpha&redirect_uri=");

            transaction2.Response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
            transaction2.ResponseToken["error"].Value <string>().ShouldBe("invalid_grant");
        }
Example #5
0
        public async Task CodeFlowFailsWhenPublicClientDoesProvideCredentials()
        {
            var server = new OAuth2TestServer(s => { s.OnAuthorizeEndpoint = SignInEpsilon; });

            OAuth2TestServer.Transaction transaction = await server.SendAsync("https://example.com/authorize?client_id=alpha3&response_type=code");

            NameValueCollection query = transaction.ParseRedirectQueryString();

            OAuth2TestServer.Transaction transaction2 = await server.SendAsync("https://example.com/token",
                                                                               authenticateHeader : new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes("alpha3:beta3"))),
                                                                               postBody : "grant_type=authorization_code&code=" + query["code"] + "&client_id=alpha3");

            transaction2.Response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
            transaction2.ResponseToken["error"].Value <string>().ShouldBe("invalid_client");
        }
        public async Task AccessTokenMayBeUsed()
        {
            var server = new OAuth2TestServer(s => { s.OnAuthorizeEndpoint = SignInEpsilon; });

            OAuth2TestServer.Transaction transaction1 = await server.SendAsync("https://example.com/authorize?response_type=token&client_id=alpha&redirect_uri=" + Uri.EscapeDataString("https://gamma.com/return"));

            NameValueCollection fragment = transaction1.ParseRedirectFragment();
            string accessToken = fragment.Get("access_token");

            OAuth2TestServer.Transaction transaction2 = await server.SendAsync("https://example.com/me",
                authenticateHeader: new AuthenticationHeaderValue("Bearer", accessToken));

            transaction2.Response.StatusCode.ShouldBe(HttpStatusCode.OK);
            transaction2.ResponseText.ShouldBe("epsilon");
        }
        public async Task TokenMayBeIssuedToClient()
        {
            var server = new OAuth2TestServer(s =>
            {
                s.Provider.OnGrantClientCredentials = ctx =>
                {
                    var claims = new List <Claim>
                    {
                        new Claim(ClaimsIdentity.DefaultNameClaimType, ctx.ClientId),
                    };
                    string scope = string.Join(" ", ctx.Scope);
                    if (!string.IsNullOrEmpty(scope))
                    {
                        claims.Add(new Claim("scope", scope));
                    }
                    ctx.Validated(new ClaimsIdentity(claims, "Bearer"));
                    return(Task.FromResult(0));
                };
            });

            OAuth2TestServer.Transaction transaction1 = await server.SendAsync(
                "https://example.com/token",
                authenticateHeader : new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes("alpha:beta"))),
                postBody : "grant_type=client_credentials");

            transaction1.Response.StatusCode.ShouldBe(HttpStatusCode.OK);
            var accessToken = transaction1.ResponseToken.Value <string>("access_token");

            string userName = await GetUserName(server, accessToken);

            userName.ShouldBe("alpha");
        }
        public async Task TokenMayBeIssuedToClient()
        {
            var server = new OAuth2TestServer(s =>
            {
                s.Provider.OnGrantClientCredentials = ctx =>
                {
                    var claims = new List<Claim>
                    {
                        new Claim(ClaimsIdentity.DefaultNameClaimType, ctx.ClientId),
                    };
                    string scope = string.Join(" ", ctx.Scope);
                    if (!string.IsNullOrEmpty(scope))
                    {
                        claims.Add(new Claim("scope", scope));
                    }
                    ctx.Validated(new ClaimsIdentity(claims, "Bearer"));
                    return Task.FromResult(0);
                };
            });

            OAuth2TestServer.Transaction transaction1 = await server.SendAsync(
                "https://example.com/token",
                authenticateHeader: new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes("alpha:beta"))),
                postBody: "grant_type=client_credentials");

            transaction1.Response.StatusCode.ShouldBe(HttpStatusCode.OK);
            var accessToken = transaction1.ResponseToken.Value<string>("access_token");

            string userName = await GetUserName(server, accessToken);
            userName.ShouldBe("alpha");
        }
        public async Task FailsWhenWrongOwnerCredentialsProvided(string username, string password)
        {
            var server = new OAuth2TestServer(s =>
            {
                LookupClient(s.Provider, "one", null, null);
                s.Provider.OnGrantResourceOwnerCredentials = GrantResourceOwnerCredentials("the-username", "the-password");
            });

            LastLookupClientId.ShouldBe(null);

            string body = "grant_type=password&client_id=one";

            if (username != null)
            {
                body += "&username="******"&password="******"https://example.com/token",
                postBody : body);

            LastLookupClientId.ShouldBe("one");

            transaction1.Response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
            transaction1.ResponseToken.Value <string>("error").ShouldBe("invalid_grant");
        }
Example #10
0
        public async Task CodeCanBeExchangedForToken()
        {
            var server = new OAuth2TestServer
            {
                OnAuthorizeEndpoint = SignInEpsilon
            };

            OAuth2TestServer.Transaction transaction = await server.SendAsync("https://example.com/authorize?client_id=alpha3&response_type=code");

            NameValueCollection query = transaction.ParseRedirectQueryString();

            OAuth2TestServer.Transaction transaction2 = await server.SendAsync("https://example.com/token", postBody :
                                                                               "grant_type=authorization_code&code=" + query["code"] + "&client_id=alpha3");

            transaction2.ResponseToken["access_token"].Value <string>().ShouldNotBe(null);
            transaction2.ResponseToken["token_type"].Value <string>().ShouldBe("bearer");
        }
        private async Task <string> GetUserName(OAuth2TestServer server, string accessToken)
        {
            OAuth2TestServer.Transaction transaction = await server.SendAsync("https://example.com/me",
                                                                              authenticateHeader : new AuthenticationHeaderValue("Bearer", accessToken));

            transaction.Response.StatusCode.ShouldBe(HttpStatusCode.OK);
            return(transaction.ResponseText);
        }
        private async Task<string> GetUserName(OAuth2TestServer server, string accessToken)
        {
            OAuth2TestServer.Transaction transaction = await server.SendAsync("https://example.com/me",
                authenticateHeader: new AuthenticationHeaderValue("Bearer", accessToken));

            transaction.Response.StatusCode.ShouldBe(HttpStatusCode.OK);
            return transaction.ResponseText;
        }
Example #13
0
        public async Task UnsupportedResponseTypeRedirectsWithErrorMessage()
        {
            var server = new OAuth2TestServer();

            OAuth2TestServer.Transaction transaction = await server.SendAsync("https://example.com/authorize?client_id=alpha&response_type=delta");

            transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
            transaction.Response.Headers.Location.Query.ShouldContain("error=unsupported_response_type");
        }
        public async Task MissingClientIdDoesNotRedirect()
        {
            var server = new OAuth2TestServer();

            OAuth2TestServer.Transaction transaction = await server.SendAsync("https://example.com/authorize");

            transaction.Response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
            transaction.ResponseText.ShouldContain("invalid_request");
        }
        public async Task BadClientIdDoesNotRedirect()
        {
            var server = new OAuth2TestServer();

            OAuth2TestServer.Transaction transaction1 = await server.SendAsync("https://example.com/authorize?response_type=token&client_id=wrong");

            transaction1.Response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
            transaction1.ResponseText.ShouldContain("invalid_request");
        }
Example #16
0
        public async Task MissingClientIdDoesNotRedirect()
        {
            var server = new OAuth2TestServer();

            OAuth2TestServer.Transaction transaction = await server.SendAsync("https://example.com/authorize");

            transaction.Response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
            transaction.ResponseText.ShouldContain("invalid_request");
        }
        public async Task IncorrectRedirectUriDoesNotRedirect()
        {
            var server = new OAuth2TestServer();

            OAuth2TestServer.Transaction transaction1 = await server.SendAsync("https://example.com/authorize?response_type=token&client_id=alpha&redirect_uri=" + Uri.EscapeDataString("http://gamma2.com/return"));

            transaction1.Response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
            transaction1.ResponseText.ShouldContain("invalid_request");
        }
        public async Task UnsupportedResponseTypeRedirectsWithErrorMessage()
        {
            var server = new OAuth2TestServer();

            OAuth2TestServer.Transaction transaction = await server.SendAsync("https://example.com/authorize?client_id=alpha&response_type=delta");

            transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
            transaction.Response.Headers.Location.Query.ShouldContain("error=unsupported_response_type");
        }
Example #19
0
        public async Task IncorrectRedirectUriDoesNotRedirect()
        {
            var server = new OAuth2TestServer();

            OAuth2TestServer.Transaction transaction = await server.SendAsync("https://example.com/authorize?client_id=alpha&redirect_uri=" + Uri.EscapeDataString("http://wrongplace.com/"));

            transaction.Response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
            transaction.ResponseText.ShouldContain("invalid_request");
        }
Example #20
0
        public async Task MissingResponseTypeRedirectsWithErrorMessage()
        {
            var server = new OAuth2TestServer();

            OAuth2TestServer.Transaction transaction = await server.SendAsync("https://example.com/authorize?client_id=alpha");

            transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
            transaction.Response.Headers.Location.Query.ShouldContain("error=invalid_request");
        }
        public async Task MissingResponseTypeRedirectsWithErrorMessage()
        {
            var server = new OAuth2TestServer();

            OAuth2TestServer.Transaction transaction = await server.SendAsync("https://example.com/authorize?client_id=alpha");

            transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
            transaction.Response.Headers.Location.Query.ShouldContain("error=invalid_request");
        }
        public async Task BadClientIdDoesNotRedirect()
        {
            var server = new OAuth2TestServer();

            OAuth2TestServer.Transaction transaction1 = await server.SendAsync("https://example.com/authorize?response_type=token&client_id=wrong");

            transaction1.Response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
            transaction1.ResponseText.ShouldContain("invalid_request");
        }
Example #23
0
        public async Task CodeFlowSucceedsWhenPublicClientDoesNotProvideCredentials()
        {
            var server = new OAuth2TestServer(s => { s.OnAuthorizeEndpoint = SignInEpsilon; });

            OAuth2TestServer.Transaction transaction = await server.SendAsync("https://example.com/authorize?client_id=alpha3&response_type=code");

            NameValueCollection query = transaction.ParseRedirectQueryString();

            OAuth2TestServer.Transaction transaction2 = await server.SendAsync("https://example.com/token",
                                                                               postBody : "grant_type=authorization_code&code=" + query["code"] + "&client_id=alpha3");

            var accessToken = transaction2.ResponseToken["access_token"].Value <string>();

            OAuth2TestServer.Transaction transaction3 = await server.SendAsync("https://example.com/me",
                                                                               authenticateHeader : new AuthenticationHeaderValue("Bearer", accessToken));

            transaction3.Response.StatusCode.ShouldBe(HttpStatusCode.OK);
            transaction3.ResponseText.ShouldBe("epsilon");
        }
        public async Task StateShouldBePassedBack()
        {
            var server = new OAuth2TestServer(s => { s.OnAuthorizeEndpoint = SignInEpsilon; });

            OAuth2TestServer.Transaction transaction1 = await server.SendAsync("https://example.com/authorize?response_type=token&client_id=alpha&state=123");

            NameValueCollection fragment = transaction1.ParseRedirectFragment();
            fragment.Get("access_token").ShouldNotBe(null);
            fragment.Get("state").ShouldBe("123");
        }
        public async Task ShouldRedirectWithParametersInFragment()
        {
            var server = new OAuth2TestServer(s => { s.OnAuthorizeEndpoint = SignInEpsilon; });

            OAuth2TestServer.Transaction transaction1 = await server.SendAsync("https://example.com/authorize?response_type=token&client_id=alpha&redirect_uri=" + Uri.EscapeDataString("https://gamma.com/return"));

            NameValueCollection fragment = transaction1.ParseRedirectFragment();
            fragment.Get("access_token").ShouldNotBe(null);
            fragment.Get("expires_in").ShouldNotBe(null);
        }
        public async Task MissingClientCredentialsFails()
        {
            var server = new OAuth2TestServer();

            OAuth2TestServer.Transaction transaction1 = await server.SendAsync(
                "https://example.com/token",
                postBody: "grant_type=client_credentials");

            transaction1.Response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
            transaction1.ResponseToken.Value<string>("error").ShouldBe("invalid_client");
        }
Example #27
0
        public async Task CodeFlowClientIdMustMatch()
        {
            var server = new OAuth2TestServer(s =>
            {
                s.Options.AuthorizationCodeExpireTimeSpan = TimeSpan.FromMinutes(5);
                s.Options.AccessTokenExpireTimeSpan       = TimeSpan.FromMinutes(60);
                s.OnAuthorizeEndpoint = SignInEpsilon;
            });

            OAuth2TestServer.Transaction transaction = await server.SendAsync("https://example.com/authorize?client_id=alpha&response_type=code");

            NameValueCollection query = transaction.ParseRedirectQueryString();

            OAuth2TestServer.Transaction transaction2 = await server.SendAsync("https://example.com/token",
                                                                               authenticateHeader : new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes("alpha2:beta2"))),
                                                                               postBody : "grant_type=authorization_code&code=" + query["code"] + "&client_id=alpha2");

            transaction2.Response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
            transaction2.ResponseToken["error"].Value <string>().ShouldBe("invalid_grant");
        }
        public async Task MissingClientCredentialsFails()
        {
            var server = new OAuth2TestServer(s => { s.Provider.OnGrantCustomExtension = ValidateCustomGrant; });

            OAuth2TestServer.Transaction transaction1 = await server.SendAsync(
                "https://example.com/token",
                postBody : "grant_type=urn:example:register");

            transaction1.Response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
            transaction1.ResponseToken.Value <string>("error").ShouldBe("invalid_client");
        }
        public async Task StateMustBePassedBackOnError()
        {
            var server = new OAuth2TestServer();

            OAuth2TestServer.Transaction transaction1 = await server.SendAsync("https://example.com/authorize?response_type=token&client_id=unauthorized&state=123&redirect_uri=" + Uri.EscapeDataString("https://gamma.com/return"));

            NameValueCollection queryStringWithState = transaction1.ParseRedirectQueryString();

            queryStringWithState.Get("access_token").ShouldBe(null);
            queryStringWithState.Get("error").ShouldBe("unauthorized_client");
            queryStringWithState.Get("state").ShouldBe("123");

            OAuth2TestServer.Transaction transaction2 = await server.SendAsync("https://example.com/authorize?response_type=token&client_id=unauthorized&redirect_uri=" + Uri.EscapeDataString("https://gamma.com/return"));

            NameValueCollection queryStringNoState = transaction2.ParseRedirectQueryString();

            queryStringNoState.Get("access_token").ShouldBe(null);
            queryStringNoState.Get("error").ShouldBe("unauthorized_client");
            queryStringNoState.Get("state").ShouldBe(null);
        }
        public async Task MissingClientCredentialsFails()
        {
            var server = new OAuth2TestServer();

            OAuth2TestServer.Transaction transaction1 = await server.SendAsync(
                "https://example.com/token",
                postBody : "grant_type=client_credentials");

            transaction1.Response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
            transaction1.ResponseToken.Value <string>("error").ShouldBe("invalid_client");
        }
        public async Task StateShouldBePassedBack()
        {
            var server = new OAuth2TestServer(s => { s.OnAuthorizeEndpoint = SignInEpsilon; });

            OAuth2TestServer.Transaction transaction1 = await server.SendAsync("https://example.com/authorize?response_type=token&client_id=alpha&state=123");

            NameValueCollection fragment = transaction1.ParseRedirectFragment();

            fragment.Get("access_token").ShouldNotBe(null);
            fragment.Get("state").ShouldBe("123");
        }
        public async Task MissingClientCredentialsFails()
        {
            var server = new OAuth2TestServer(s => { s.Provider.OnGrantCustomExtension = ValidateCustomGrant; });

            OAuth2TestServer.Transaction transaction1 = await server.SendAsync(
                "https://example.com/token",
                postBody: "grant_type=urn:example:register");

            transaction1.Response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
            transaction1.ResponseToken.Value<string>("error").ShouldBe("invalid_client");
        }
        public async Task ShouldRedirectWithParametersInFragment()
        {
            var server = new OAuth2TestServer(s => { s.OnAuthorizeEndpoint = SignInEpsilon; });

            OAuth2TestServer.Transaction transaction1 = await server.SendAsync("https://example.com/authorize?response_type=token&client_id=alpha&redirect_uri=" + Uri.EscapeDataString("https://gamma.com/return"));

            NameValueCollection fragment = transaction1.ParseRedirectFragment();

            fragment.Get("access_token").ShouldNotBe(null);
            fragment.Get("expires_in").ShouldNotBe(null);
        }
        public async Task NonPermittedClientFails()
        {
            var server = new OAuth2TestServer();

            OAuth2TestServer.Transaction transaction1 = await server.SendAsync(
                "https://example.com/token",
                authenticateHeader : new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes("alpha:beta"))),
                postBody : "grant_type=client_credentials");

            transaction1.Response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
            transaction1.ResponseToken.Value <string>("error").ShouldBe("unauthorized_client");
        }
        public async Task UnrecognizedClientCredentialsFails()
        {
            var server = new OAuth2TestServer(s => { s.Provider.OnGrantCustomExtension = ValidateCustomGrant; });

            OAuth2TestServer.Transaction transaction1 = await server.SendAsync(
                "https://example.com/token",
                authenticateHeader : new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes("bad:data"))),
                postBody : "grant_type=urn:example:register");

            transaction1.Response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
            transaction1.ResponseToken.Value <string>("error").ShouldBe("invalid_client");
        }
        public async Task UnrecognizedParametersAreIgnored()
        {
            var server = new OAuth2TestServer(s => { s.OnAuthorizeEndpoint = SignInEpsilon; });

            OAuth2TestServer.Transaction transaction1 = await server.SendAsync("https://example.com/authorize?alpha=beta&response_type=token&client_id=alpha&redirect_uri=" + Uri.EscapeDataString("https://gamma.com/return"));

            NameValueCollection fragment = transaction1.ParseRedirectFragment();

            string userName = await GetUserName(server, fragment.Get("access_token"));

            userName.ShouldBe("epsilon");
        }
        public async Task NonPermittedClientFails()
        {
            var server = new OAuth2TestServer();

            OAuth2TestServer.Transaction transaction1 = await server.SendAsync(
                "https://example.com/token",
                authenticateHeader: new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes("alpha:beta"))),
                postBody: "grant_type=client_credentials");

            transaction1.Response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
            transaction1.ResponseToken.Value<string>("error").ShouldBe("unauthorized_client");
        }
        public async Task BadUtf8ClientCredentialsFails()
        {
            var server = new OAuth2TestServer();

            OAuth2TestServer.Transaction transaction1 = await server.SendAsync(
                "https://example.com/token",
                authenticateHeader: new AuthenticationHeaderValue("Basic", Convert.ToBase64String(new byte[] { 0x8F, 0x90 })),
                postBody: "grant_type=client_credentials");

            transaction1.Response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
            transaction1.ResponseToken.Value<string>("error").ShouldBe("invalid_client");
        }
        public async Task UnrecognizedClientCredentialsFails()
        {
            var server = new OAuth2TestServer(s => { s.Provider.OnGrantCustomExtension = ValidateCustomGrant; });

            OAuth2TestServer.Transaction transaction1 = await server.SendAsync(
                "https://example.com/token",
                authenticateHeader: new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes("bad:data"))),
                postBody: "grant_type=urn:example:register");

            transaction1.Response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
            transaction1.ResponseToken.Value<string>("error").ShouldBe("invalid_client");
        }
        public async Task BadUtf8ClientCredentialsFails()
        {
            var server = new OAuth2TestServer();

            OAuth2TestServer.Transaction transaction1 = await server.SendAsync(
                "https://example.com/token",
                authenticateHeader : new AuthenticationHeaderValue("Basic", Convert.ToBase64String(new byte[] { 0x8F, 0x90 })),
                postBody : "grant_type=client_credentials");

            transaction1.Response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
            transaction1.ResponseToken.Value <string>("error").ShouldBe("invalid_client");
        }
Example #41
0
        public async Task AccessTokenWillExpire()
        {
            var server = new OAuth2TestServer(s =>
            {
                s.Options.AuthorizationCodeExpireTimeSpan = TimeSpan.FromMinutes(5);
                s.Options.AccessTokenExpireTimeSpan       = TimeSpan.FromMinutes(60);
                s.OnAuthorizeEndpoint = SignInEpsilon;
            });

            OAuth2TestServer.Transaction transaction = await server.SendAsync("https://example.com/authorize?client_id=alpha&response_type=code");

            NameValueCollection query = transaction.ParseRedirectQueryString();

            OAuth2TestServer.Transaction transaction2 = await server.SendAsync("https://example.com/token",
                                                                               authenticateHeader : new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes("alpha:beta"))),
                                                                               postBody : "grant_type=authorization_code&code=" + query["code"] + "&client_id=alpha");

            var accessToken = transaction2.ResponseToken["access_token"].Value <string>();

            OAuth2TestServer.Transaction transaction3 = await server.SendAsync("https://example.com/me",
                                                                               authenticateHeader : new AuthenticationHeaderValue("Bearer", accessToken));

            transaction3.Response.StatusCode.ShouldBe(HttpStatusCode.OK);
            transaction3.ResponseText.ShouldBe("epsilon");

            server.Clock.Add(TimeSpan.FromMinutes(45));

            OAuth2TestServer.Transaction transaction4 = await server.SendAsync("https://example.com/me",
                                                                               authenticateHeader : new AuthenticationHeaderValue("Bearer", accessToken));

            transaction4.Response.StatusCode.ShouldBe(HttpStatusCode.OK);
            transaction3.ResponseText.ShouldBe("epsilon");

            server.Clock.Add(TimeSpan.FromMinutes(20));

            OAuth2TestServer.Transaction transaction5 = await server.SendAsync("https://example.com/me",
                                                                               authenticateHeader : new AuthenticationHeaderValue("Bearer", accessToken));

            transaction5.Response.StatusCode.ShouldBe(HttpStatusCode.Unauthorized);
        }
Example #42
0
        public async Task CodeFlowWillFailIfRedirectUriOriginallyIncorrect()
        {
            var server = new OAuth2TestServer(s =>
            {
                s.Options.AuthorizationCodeExpireTimeSpan = TimeSpan.FromMinutes(5);
                s.Options.AccessTokenExpireTimeSpan       = TimeSpan.FromMinutes(60);
                s.OnAuthorizeEndpoint = SignInEpsilon;
            });

            OAuth2TestServer.Transaction transaction = await server.SendAsync("https://example.com/authorize?client_id=alpha&response_type=code&redirect_uri=" + Uri.EscapeDataString("https://gamma2.com/return"));

            transaction.Response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
        }
Example #43
0
        public async Task RefreshTokenMayBeUsedToGetNewAccessToken()
        {
            var server = new OAuth2TestServer(s =>
            {
                s.Options.RefreshTokenProvider = new AuthenticationTokenProvider
                {
                    OnCreate  = ctx => ctx.SetToken(ctx.SerializeTicket()),
                    OnReceive = ctx => ctx.DeserializeTicket(ctx.Token),
                };
                s.OnAuthorizeEndpoint = SignInEpsilon;
            });

            OAuth2TestServer.Transaction transaction = await server.SendAsync("https://example.com/authorize?client_id=alpha&response_type=code");

            NameValueCollection query = transaction.ParseRedirectQueryString();

            OAuth2TestServer.Transaction transaction2 = await server.SendAsync("https://example.com/token",
                                                                               authenticateHeader : new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes("alpha:beta"))),
                                                                               postBody : "grant_type=authorization_code&code=" + query["code"] + "&client_id=alpha");

            var accessToken  = transaction2.ResponseToken["access_token"].Value <string>();
            var refreshToken = transaction2.ResponseToken["refresh_token"].Value <string>();

            accessToken.ShouldNotBe(null);
            refreshToken.ShouldNotBe(null);

            OAuth2TestServer.Transaction transaction3 = await server.SendAsync("https://example.com/token",
                                                                               authenticateHeader : new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes("alpha:beta"))),
                                                                               postBody : "grant_type=refresh_token&refresh_token=" + refreshToken);

            var accessToken2  = transaction3.ResponseToken["access_token"].Value <string>();
            var refreshToken2 = transaction3.ResponseToken["refresh_token"].Value <string>();

            accessToken2.ShouldNotBe(null);
            refreshToken2.ShouldNotBe(null);
            accessToken2.ShouldNotBe(accessToken);
            refreshToken2.ShouldNotBe(refreshToken);
        }
        public async Task ResourceOwnerFailsWithoutClientWhenNotExplicitlyEnabled()
        {
            var server = new OAuth2TestServer(s =>
            {
                LookupClient(s.Provider, "one", null, null);
                s.Provider.OnGrantResourceOwnerCredentials = GrantResourceOwnerCredentials("the-username", "the-password");
            });

            OAuth2TestServer.Transaction transaction1 = await server.SendAsync(
                "https://example.com/token",
                postBody: "grant_type=password&username=the-username&password=the-password");

            transaction1.Response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
            transaction1.ResponseToken.Value<string>("error").ShouldBe("invalid_client");
        }
        public async Task TokenMayBeIssuedWithCustomGrantType()
        {
            var server = new OAuth2TestServer(s => { s.Provider.OnGrantCustomExtension = ValidateCustomGrant; });

            OAuth2TestServer.Transaction transaction1 = await server.SendAsync(
                "https://example.com/token",
                authenticateHeader: new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes("alpha2:beta2"))),
                postBody: "grant_type=urn:example:register&alias=one");

            transaction1.Response.StatusCode.ShouldBe(HttpStatusCode.OK);
            var accessToken = transaction1.ResponseToken.Value<string>("access_token");

            string userName = await GetUserName(server, accessToken);
            userName.ShouldBe("one");
        }
        public async Task ResourceOwnerFailsWithoutClientWhenNotExplicitlyEnabled()
        {
            var server = new OAuth2TestServer(s =>
            {
                LookupClient(s.Provider, "one", null, null);
                s.Provider.OnGrantResourceOwnerCredentials = GrantResourceOwnerCredentials("the-username", "the-password");
            });

            OAuth2TestServer.Transaction transaction1 = await server.SendAsync(
                "https://example.com/token",
                postBody : "grant_type=password&username=the-username&password=the-password");

            transaction1.Response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
            transaction1.ResponseToken.Value <string>("error").ShouldBe("invalid_client");
        }
Example #47
0
        public async Task CallingSignInWillRedirectWithAuthorizationCode()
        {
            var server = new OAuth2TestServer
            {
                OnAuthorizeEndpoint = ctx =>
                {
                    ctx.Authentication.SignIn(new AuthenticationProperties(), CreateIdentity("epsilon"));
                    return(Task.FromResult <object>(null));
                }
            };

            OAuth2TestServer.Transaction transaction = await server.SendAsync("https://example.com/authorize?client_id=alpha&response_type=code");

            transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
            transaction.Response.Headers.Location.Query.ShouldContain("code=");
        }
        public async Task AuthorizeRequestMayPassThroughToApplicationRequestHandler()
        {
            var server = new OAuth2TestServer
            {
                OnAuthorizeEndpoint = async ctx =>
                {
                    ctx.Response.ContentType = "text/plain";
                    using (var writer = new StreamWriter(ctx.Response.Body, Encoding.UTF8, 4096, leaveOpen: true))
                    {
                        await writer.WriteAsync("Responding");
                    }
                }
            };

            OAuth2TestServer.Transaction transaction = await server.SendAsync("https://example.com/authorize?client_id=alpha&response_type=code");
            transaction.Response.StatusCode.ShouldBe(HttpStatusCode.OK);
            transaction.ResponseText.ShouldBe("Responding");
        }
        public async Task ResourceOwnerCanSucceedWithoutClientId()
        {
            var server = new OAuth2TestServer(s =>
            {
                s.Provider.OnValidateClientAuthentication = ctx =>
                {
                    ctx.Validated();
                    return Task.FromResult(0);
                };
                s.Provider.OnGrantResourceOwnerCredentials = GrantResourceOwnerCredentials("the-username", "the-password");
            });

            OAuth2TestServer.Transaction transaction1 = await server.SendAsync(
                "https://example.com/token",
                postBody: "grant_type=password&username=the-username&password=the-password");

            transaction1.Response.StatusCode.ShouldBe(HttpStatusCode.OK);
            var accessToken = transaction1.ResponseToken.Value<string>("access_token");

            string userName = await GetUserName(server, accessToken);
            userName.ShouldBe("the-username");
        }
        public async Task ResourceOwnerCanSucceedWithPublicClient()
        {
            var server = new OAuth2TestServer(s =>
            {
                LookupClient(s.Provider, "one", null, "https://example.com/return");
                s.Provider.OnGrantResourceOwnerCredentials = GrantResourceOwnerCredentials("the-username", "the-password");
            });

            LastLookupClientId.ShouldBe(null);

            OAuth2TestServer.Transaction transaction1 = await server.SendAsync(
                "https://example.com/token",
                postBody: "grant_type=password&username=the-username&password=the-password&client_id=one");

            LastLookupClientId.ShouldBe("one");

            transaction1.Response.StatusCode.ShouldBe(HttpStatusCode.OK);
            var accessToken = transaction1.ResponseToken.Value<string>("access_token");

            string userName = await GetUserName(server, accessToken);
            userName.ShouldBe("the-username");
        }
        public async Task CodeFlowFailsWhenPublicClientDoesProvideCredentials()
        {
            var server = new OAuth2TestServer(s => { s.OnAuthorizeEndpoint = SignInEpsilon; });

            OAuth2TestServer.Transaction transaction = await server.SendAsync("https://example.com/authorize?client_id=alpha3&response_type=code");

            NameValueCollection query = transaction.ParseRedirectQueryString();

            OAuth2TestServer.Transaction transaction2 = await server.SendAsync("https://example.com/token",
                authenticateHeader: new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes("alpha3:beta3"))),
                postBody: "grant_type=authorization_code&code=" + query["code"] + "&client_id=alpha3");

            transaction2.Response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
            transaction2.ResponseToken["error"].Value<string>().ShouldBe("invalid_client");
        }
        public async Task ResourceOwnerFailsWhenPublicClientProvidesCredentials()
        {
            var server = new OAuth2TestServer(s =>
            {
                LookupClient(s.Provider, "one", null, "https://example.com/return");
                s.Provider.OnGrantResourceOwnerCredentials = GrantResourceOwnerCredentials("the-username", "the-password");
            });

            LastLookupClientId.ShouldBe(null);

            OAuth2TestServer.Transaction transaction1 = await server.SendAsync(
                "https://example.com/token",
                authenticateHeader: new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes("one:two"))),
                postBody: "grant_type=password&username=the-username&password=the-password&client_id=one");

            LastLookupClientId.ShouldBe("one");

            transaction1.Response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
            transaction1.ResponseToken.Value<string>("error").ShouldBe("invalid_client");
        }
        public async Task CustomGrantTypeMaySendSpecificError()
        {
            var server = new OAuth2TestServer(s =>
            {
                s.Provider.OnGrantCustomExtension = ctx =>
                {
                    ctx.SetError("one", "two", "three");
                    return Task.FromResult(0);
                };
            });

            OAuth2TestServer.Transaction transaction1 = await server.SendAsync(
                "https://example.com/token",
                authenticateHeader: new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes("alpha:beta"))),
                postBody: "grant_type=urn:example:register&alias=one");

            transaction1.Response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
            transaction1.ResponseToken.Value<string>("error").ShouldBe("one");
            transaction1.ResponseToken.Value<string>("error_description").ShouldBe("two");
            transaction1.ResponseToken.Value<string>("error_uri").ShouldBe("three");
        }
        public async Task ResourceOwnerCanSucceedWithConfidentialClient()
        {
            var server = new OAuth2TestServer(s =>
            {
                LookupClient(s.Provider, "one", "two", "https://example.com/return");
                s.Provider.OnGrantResourceOwnerCredentials = GrantResourceOwnerCredentials("the-username", "the-password");
            });

            LastLookupClientId.ShouldBe(null);

            OAuth2TestServer.Transaction transaction1 = await server.SendAsync(
                "https://example.com/token",
                authenticateHeader: new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes("one:two"))),
                postBody: "grant_type=password&username=the-username&password=the-password");

            LastLookupClientId.ShouldBe("one");

            transaction1.Response.StatusCode.ShouldBe(HttpStatusCode.OK);
            var accessToken = transaction1.ResponseToken.Value<string>("access_token");

            string userName = await GetUserName(server, accessToken);
            userName.ShouldBe("the-username");
        }
        public async Task FailsWhenWrongOwnerCredentialsProvided(string username, string password)
        {
            var server = new OAuth2TestServer(s =>
            {
                LookupClient(s.Provider, "one", null, null);
                s.Provider.OnGrantResourceOwnerCredentials = GrantResourceOwnerCredentials("the-username", "the-password");
            });

            LastLookupClientId.ShouldBe(null);

            string body = "grant_type=password&client_id=one";
            if (username != null)
            {
                body += "&username="******"&password="******"https://example.com/token",
                postBody: body);

            LastLookupClientId.ShouldBe("one");

            transaction1.Response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
            transaction1.ResponseToken.Value<string>("error").ShouldBe("invalid_grant");
        }
        public async Task FailsWhenWrongPasswordProvided()
        {
            var server = new OAuth2TestServer(s =>
            {
                LookupClient(s.Provider, "one", "two", "https://example.com/return");
                s.Provider.OnGrantResourceOwnerCredentials = GrantResourceOwnerCredentials("the-username", "the-password");
            });

            LastLookupClientId.ShouldBe(null);

            OAuth2TestServer.Transaction transaction1 = await server.SendAsync(
                "https://example.com/token",
                postBody: "grant_type=password&username=the-username&password=the-password&client_id=one");

            LastLookupClientId.ShouldBe("one");

            transaction1.Response.StatusCode.ShouldBe(HttpStatusCode.BadRequest);
            transaction1.ResponseToken.Value<string>("error").ShouldBe("invalid_client");
        }
        public async Task CallingSignInWillRedirectWithAuthorizationCode()
        {
            var server = new OAuth2TestServer
            {
                OnAuthorizeEndpoint = ctx =>
                {
                    ctx.Authentication.SignIn(new AuthenticationProperties(), CreateIdentity("epsilon"));
                    return Task.FromResult<object>(null);
                }
            };

            OAuth2TestServer.Transaction transaction = await server.SendAsync("https://example.com/authorize?client_id=alpha&response_type=code");
            transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
            transaction.Response.Headers.Location.Query.ShouldContain("code=");
        }
        public async Task CodeFlowSucceedsWhenConfidentialClientDoesNotProvideClientIdToTokenEndpoint()
        {
            var server = new OAuth2TestServer(s => { s.OnAuthorizeEndpoint = SignInEpsilon; });

            OAuth2TestServer.Transaction transaction = await server.SendAsync("https://example.com/authorize?client_id=alpha&response_type=code");

            NameValueCollection query = transaction.ParseRedirectQueryString();

            OAuth2TestServer.Transaction transaction2 = await server.SendAsync("https://example.com/token",
                authenticateHeader: new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes("alpha:beta"))),
                postBody: "grant_type=authorization_code&code=" + query["code"]);

            var accessToken = transaction2.ResponseToken["access_token"].Value<string>();

            OAuth2TestServer.Transaction transaction3 = await server.SendAsync("https://example.com/me",
                authenticateHeader: new AuthenticationHeaderValue("Bearer", accessToken));

            transaction3.Response.StatusCode.ShouldBe(HttpStatusCode.OK);
            transaction3.ResponseText.ShouldBe("epsilon");
        }
        public async Task UnrecognizedParametersAreIgnored()
        {
            var server = new OAuth2TestServer(s => { s.OnAuthorizeEndpoint = SignInEpsilon; });

            OAuth2TestServer.Transaction transaction1 = await server.SendAsync("https://example.com/authorize?alpha=beta&response_type=token&client_id=alpha&redirect_uri=" + Uri.EscapeDataString("https://gamma.com/return"));

            NameValueCollection fragment = transaction1.ParseRedirectFragment();

            string userName = await GetUserName(server, fragment.Get("access_token"));
            userName.ShouldBe("epsilon");
        }
        public async Task TokenGrantsMayCarryAdditionalResponseParameters()
        {
            var server = new OAuth2TestServer(s =>
            {
                s.Provider.OnGrantCustomExtension = ValidateCustomGrant;
                s.Provider.OnTokenEndpoint = ctx =>
                {
                    ctx.AdditionalResponseParameters["is_registered"] = false;
                    ctx.AdditionalResponseParameters["server_time"] = s.Clock.UtcNow.DateTime;
                    ctx.AdditionalResponseParameters["username"] = ctx.Identity.Name;
                    return Task.FromResult(0);
                };
            });

            OAuth2TestServer.Transaction transaction1 = await server.SendAsync(
                "https://example.com/token",
                authenticateHeader: new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes("alpha2:beta2"))),
                postBody: "grant_type=urn:example:register&alias=two");

            transaction1.Response.StatusCode.ShouldBe(HttpStatusCode.OK);
            transaction1.ResponseToken.Value<bool>("is_registered").ShouldBe(false);
            transaction1.ResponseToken.Value<DateTime>("server_time").ShouldBe(server.Clock.UtcNow.DateTime);
            transaction1.ResponseToken.Value<string>("username").ShouldBe("two");
        }