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