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"); }
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"); }
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"); }
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"); }
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; }
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"); }
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 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"); }
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 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"); }
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 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 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"); }
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); }
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); }
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"); }
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 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"); }