#417 Update facebook to latest API versions

This commit is contained in:
Chris R 2017-01-30 12:39:55 -08:00
Родитель 49b78c0874
Коммит b32efb31da
6 изменённых файлов: 94 добавлений и 32 удалений

Просмотреть файл

@ -6,8 +6,8 @@ namespace Microsoft.Owin.Security.Facebook
{
public const string DefaultAuthenticationType = "Facebook";
internal const string AuthorizationEndpoint = "https://www.facebook.com/dialog/oauth";
internal const string TokenEndpoint = "https://graph.facebook.com/oauth/access_token";
internal const string UserInformationEndpoint = "https://graph.facebook.com/me";
internal const string AuthorizationEndpoint = "https://www.facebook.com/v2.8/dialog/oauth";
internal const string TokenEndpoint = "https://graph.facebook.com/v2.8/oauth/access_token";
internal const string UserInformationEndpoint = "https://graph.facebook.com/v2.8/me";
}
}

Просмотреть файл

@ -87,14 +87,25 @@ namespace Microsoft.Owin.Security.Facebook
HttpResponseMessage tokenResponse = await _httpClient.GetAsync(Options.TokenEndpoint + "?" + tokenRequest, Request.CallCancelled);
tokenResponse.EnsureSuccessStatusCode();
string text = await tokenResponse.Content.ReadAsStringAsync();
IFormCollection form = WebHelpers.ParseForm(text);
JObject response = JObject.Parse(text);
string accessToken = form["access_token"];
string expires = form["expires"];
string graphAddress = Options.UserInformationEndpoint + "?access_token=" + Uri.EscapeDataString(accessToken);
string accessToken = response.Value<string>("access_token");
if (string.IsNullOrWhiteSpace(accessToken))
{
_logger.WriteWarning("Access token was not found");
return new AuthenticationTicket(null, properties);
}
string expires = response.Value<string>("expires_in");
string graphAddress = WebUtilities.AddQueryString(Options.UserInformationEndpoint, "access_token", accessToken);
if (Options.SendAppSecretProof)
{
graphAddress += "&appsecret_proof=" + GenerateAppSecretProof(accessToken);
graphAddress = WebUtilities.AddQueryString(graphAddress, "&appsecret_proof", GenerateAppSecretProof(accessToken));
}
if (Options.Fields.Count > 0)
{
graphAddress = WebUtilities.AddQueryString(graphAddress, "fields", string.Join(",", Options.Fields));
}
HttpResponseMessage graphResponse = await _httpClient.GetAsync(graphAddress, Request.CallCancelled);

Просмотреть файл

@ -27,6 +27,7 @@ namespace Microsoft.Owin.Security.Facebook
Scope = new List<string>();
BackchannelTimeout = TimeSpan.FromSeconds(60);
SendAppSecretProof = true;
Fields = new List<string>();
AuthorizationEndpoint = Constants.AuthorizationEndpoint;
TokenEndpoint = Constants.TokenEndpoint;
@ -45,19 +46,16 @@ namespace Microsoft.Owin.Security.Facebook
/// <summary>
/// Gets or sets the URI where the client will be redirected to authenticate.
/// The default value is 'https://www.facebook.com/dialog/oauth'.
/// </summary>
public string AuthorizationEndpoint { get; set; }
/// <summary>
/// Gets or sets the URI the middleware will access to exchange the OAuth token.
/// The default value is 'https://graph.facebook.com/oauth/access_token'.
/// </summary>
public string TokenEndpoint { get; set; }
/// <summary>
/// Gets or sets the URI the middleware will access to obtain the user information.
/// The default value is 'https://graph.facebook.com/me'.
/// </summary>
public string UserInformationEndpoint { get; set; }
@ -129,6 +127,12 @@ namespace Microsoft.Owin.Security.Facebook
/// </summary>
public bool SendAppSecretProof { get; set; }
/// <summary>
/// The list of fields to retrieve from the UserInformationEndpoint.
/// https://developers.facebook.com/docs/graph-api/reference/user
/// </summary>
public IList<string> Fields { get; }
/// <summary>
/// An abstraction for reading and setting cookies during the authentication process.
/// </summary>

Просмотреть файл

@ -34,7 +34,7 @@ namespace FunctionalTests.Facts.Security.Facebook
// Unauthenticated request - verify Redirect url
var response = await httpClient.GetAsync(applicationUrl);
Assert.Equal<string>("https://www.facebook.com/dialog/oauth", response.Headers.Location.AbsoluteUri.Replace(response.Headers.Location.Query, string.Empty));
Assert.Equal<string>("https://www.facebook.com/v2.8/dialog/oauth", response.Headers.Location.AbsoluteUri.Replace(response.Headers.Location.Query, string.Empty));
var queryItems = response.Headers.Location.ParseQueryString();
Assert.Equal<string>("code", queryItems["response_type"]);
Assert.Equal<string>("550624398330273", queryItems["client_id"]);
@ -181,7 +181,7 @@ namespace FunctionalTests.Facts.Security.Facebook
var response = new HttpResponseMessage();
var queryParameters = request.RequestUri.ParseQueryString();
if (request.RequestUri.AbsoluteUri.StartsWith("https://graph.facebook.com/oauth/access_token"))
if (request.RequestUri.AbsoluteUri.StartsWith("https://graph.facebook.com/v2.8/oauth/access_token"))
{
if (queryParameters["grant_type"] == "authorization_code")
{
@ -190,7 +190,7 @@ namespace FunctionalTests.Facts.Security.Facebook
Assert.True(queryParameters["redirect_uri"].EndsWith("signin-facebook"), "Redirect URI is not ending with /signin-facebook");
Assert.Equal<string>("550624398330273", queryParameters["client_id"]);
Assert.Equal<string>("10e56a291d6b618da61b1e0dae3a8954", queryParameters["client_secret"]);
response.Content = new StringContent("access_token=ValidAccessToken&expires=100");
response.Content = new StringContent("{\"access_token\":\"ValidAccessToken\",\"token_type\":\"Bearer\",\"expires_in\":\"100\"}", Encoding.UTF8, "application/json");
}
else if (queryParameters["code"] == "InvalidCert")
{
@ -222,7 +222,7 @@ namespace FunctionalTests.Facts.Security.Facebook
}
}
}
else if (request.RequestUri.AbsoluteUri.StartsWith("https://graph.facebook.com/me"))
else if (request.RequestUri.AbsoluteUri.StartsWith("https://graph.facebook.com/v2.8/me"))
{
Assert.NotEqual<string>(null, queryParameters["appsecret_proof"]);
if (queryParameters["access_token"] == "ValidAccessToken")

Просмотреть файл

@ -75,21 +75,21 @@ namespace Katana.Sandbox.WebServer
CookieManager = new SystemWebChunkingCookieManager()
});
// https://developers.facebook.com/apps/
app.UseFacebookAuthentication(new FacebookAuthenticationOptions
{
AppId = "454990987951096",
AppSecret = "ca7cbddf944f91f23c1ed776f265478e",
AuthorizationEndpoint = "https://www.facebook.com/v2.2/dialog/oauth",
TokenEndpoint = "https://graph.facebook.com/v2.2/oauth/access_token",
UserInformationEndpoint = "https://graph.facebook.com/v2.2/me",
AppId = Environment.GetEnvironmentVariable("facebook:appid"),
AppSecret = Environment.GetEnvironmentVariable("facebook:appsecret"),
Scope = { "email" },
Fields = { "name", "email" },
CookieManager = new SystemWebCookieManager()
// Scope = "email user_birthday user_website"
});
// https://console.developers.google.com/project
app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions()
{
ClientId = "1033034290282-6h0n78feiepoltpqkmsrqh1ngmeh4co7.apps.googleusercontent.com",
ClientSecret = "6l7lHh-B0_awzoTrlTGWh7km",
ClientId = Environment.GetEnvironmentVariable("google:clientid"),
ClientSecret = Environment.GetEnvironmentVariable("google:clientsecret"),
});
//// Flow to get user identifier in OpenID for migration to OAuth 2.0
@ -117,9 +117,12 @@ namespace Katana.Sandbox.WebServer
// }
//});
app.UseTwitterAuthentication("6XaCTaLbMqfj6ww3zvZ5g", "Il2eFzGIrYhz6BWjYhVXBPQSfZuS4xoHpSSyD9PI");
// https://apps.twitter.com/
// https://dev.twitter.com/web/sign-in/implementing
app.UseTwitterAuthentication(Environment.GetEnvironmentVariable("twitter:consumerkey"), Environment.GetEnvironmentVariable("twitter:consumersecret"));
app.UseMicrosoftAccountAuthentication("000000004C0EA787", "QZde5m5HHZPxdieV0lOy7bBVTbVqR9Ju");
// https://azure.microsoft.com/en-us/documentation/articles/active-directory-v2-app-registration/
app.UseMicrosoftAccountAuthentication(Environment.GetEnvironmentVariable("microsoftaccount:clientid"), Environment.GetEnvironmentVariable("microsoftaccount:clientsecret"));
// app.UseAspNetAuthSession();
/*
@ -139,8 +142,8 @@ namespace Katana.Sandbox.WebServer
app.UseOpenIdConnectAuthentication(new Microsoft.Owin.Security.OpenIdConnect.OpenIdConnectAuthenticationOptions()
{
Authority = "https://login.microsoftonline.com/tratcheroutlook.onmicrosoft.com",
ClientId = "",
Authority = Environment.GetEnvironmentVariable("oidc:authority"),
ClientId = Environment.GetEnvironmentVariable("oidc:clientid"),
RedirectUri = "https://localhost:44318/",
CookieManager = new SystemWebCookieManager()
});
@ -207,6 +210,26 @@ namespace Katana.Sandbox.WebServer
OnReceive = ReceiveRefreshToken,
}
});
*/
app.Map("/signout", map =>
{
map.Run(context =>
{
context.Authentication.SignOut("External");
var response = context.Response;
response.ContentType = "text/html";
response.Write("<body><html>Signed out. <a href=\"/\">Home</a></html></body>");
return Task.FromResult(0);
});
});
app.Map("/challenge", map =>
{
map.Run(context =>
{
context.Authentication.Challenge(new AuthenticationProperties() { RedirectUri = "/" }, context.Request.Query["scheme"]);
return Task.FromResult(0);
});
});
/*
app.Map("/Account/Login", map =>
{
@ -218,6 +241,28 @@ namespace Katana.Sandbox.WebServer
});
*/
app.Use((context, next) =>
{
var user = context.Authentication.User;
if (user == null || user.Identity == null || !user.Identity.IsAuthenticated)
{
var response = context.Response;
response.ContentType = "text/html";
response.Write("<html><body>Providers:<br>\r\n");
foreach (var provider in context.Authentication.GetAuthenticationTypes())
{
response.Write("- <a href=\"/challenge?scheme=");
response.Write(provider.AuthenticationType);
response.Write("\">");
response.Write(provider.AuthenticationType);
response.Write("</a><br>\r\n");
}
response.Write("</body></html>\r\n");
return Task.FromResult(0);
}
return next();
});
/*
app.Use((context, next) =>
{
var user = context.Authentication.User;
if (user == null || user.Identity == null || !user.Identity.IsAuthenticated)
@ -228,23 +273,25 @@ namespace Katana.Sandbox.WebServer
}
return next();
});
*/
app.Run(async context =>
{
var response = context.Response;
var user = context.Authentication.User;
var identity = user.Identities.First();
response.ContentType = "text/plain";
await response.WriteAsync("Details:\r\n");
response.ContentType = "text/html";
await response.WriteAsync("<html><body>Details:<br>\r\n");
foreach (var claim in identity.Claims)
{
response.Write("- ");
response.Write(claim.Type);
response.Write(": ");
response.Write(claim.Value);
response.Write("\r\n");
response.Write("<br>\r\n");
}
response.Write("<a href=\"/signout\">Signout</a>\r\n");
response.Write("</body></html>\r\n");
});
}

Просмотреть файл

@ -58,7 +58,7 @@ namespace Microsoft.Owin.Security.Tests.Facebook
var transaction = await SendAsync(server, "http://example.com/challenge");
transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect);
var location = transaction.Response.Headers.Location.AbsoluteUri;
location.ShouldContain("https://www.facebook.com/dialog/oauth");
location.ShouldContain("https://www.facebook.com/v2.8/dialog/oauth");
location.ShouldContain("?response_type=code");
location.ShouldContain("&client_id=");
location.ShouldContain("&redirect_uri=");