Skip to content

Instantly share code, notes, and snippets.

@howarddierking
Created October 12, 2011 03:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save howarddierking/1280196 to your computer and use it in GitHub Desktop.
Save howarddierking/1280196 to your computer and use it in GitHub Desktop.
Web API Message Handler for processing Facebook OAuth2 auth code responses
public class OAuthFacebookMessageHandler : DelegatingHandler
{
static readonly Uri FacebookBaseGraphUri = new Uri("https://graph.facebook.com/me");
static readonly Uri FacebookAccessTokenBaseUri = new Uri("https://graph.facebook.com/oauth/access_token");
readonly string _facebookAppId;
readonly string _facebookAppSecret;
public OAuthFacebookMessageHandler(string appId, string secret) {
_facebookAppId = appId;
_facebookAppSecret = secret;
}
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
CancellationToken cancellationToken) {
if (request.Method == HttpMethod.Get && request.RequestUri.Segments.Last() == "authtoken") {
var querystring = request.RequestUri.Query.Substring(1);
var queryParams = querystring.Split(new[] {'&'});
if (queryParams.Length > 0) {
var code = queryParams.Where(p => p.StartsWith("code")).First().Split(new[] {'='})[1];
return Task.Factory.StartNew(() => {
var accessToken = GetFacebookAccessToken(code, request);
var username = GetFacebookUsername(accessToken);
var ticket = new FormsAuthenticationTicket(username, false, 60);
var s = FormsAuthentication.Encrypt(ticket);
var response = new HttpResponseMessage();
response.Headers.Add("Set-Cookie", string.Format("ticket={0}; path=/", s));
var responseContentBuilder = new StringBuilder();
responseContentBuilder.AppendLine("<html>");
responseContentBuilder.AppendLine(" <head>");
responseContentBuilder.AppendLine(" <title>temp</title>");
responseContentBuilder.AppendLine(" </head>");
responseContentBuilder.AppendLine(" <body>");
responseContentBuilder.AppendLine(" <script type=\"text/javascript\">");
responseContentBuilder.AppendLine(" if(window.opener && window.opener.GetCommentsWithOAuth){");
responseContentBuilder.AppendLine(" window.opener.GetCommentsWithOAuth();");
responseContentBuilder.AppendLine(" window.close()");
responseContentBuilder.AppendLine(" }");
responseContentBuilder.AppendLine(" </script>");
responseContentBuilder.AppendLine(" </body>");
responseContentBuilder.AppendLine("</html>");
response.Content = new StringContent(responseContentBuilder.ToString());
response.Content.Headers.ContentType = new MediaTypeHeaderValue("text/html");
response.Headers.CacheControl = new CacheControlHeaderValue {NoCache = true};
return response;
});
}
return Task.Factory.StartNew(() => new HttpResponseMessage(HttpStatusCode.InternalServerError));
}
return base.SendAsync(request, cancellationToken);
}
string GetFacebookAccessToken(string code, HttpRequestMessage request) {
var uriBuilder = new UriBuilder(FacebookAccessTokenBaseUri)
{
Query = string.Format("client_id={0}&redirect_uri={1}://{2}{3}&client_secret={4}&code={5}",
_facebookAppId,
request.RequestUri.Scheme,
request.RequestUri.Authority,
request.RequestUri.LocalPath,
_facebookAppSecret,
code)
};
var accessTokenClient = new HttpClient();
var accessTokenResponse = accessTokenClient.Get(uriBuilder.Uri);
var responseBody = accessTokenResponse.Content.ReadAsString();
if (responseBody != null) {
var accessToken = responseBody.Split(new[] {'&'}).First().Split(new[] {'='})[1];
return accessToken;
}
throw new Exception("access token response body should not be null");
}
static string GetFacebookUsername(string accessToken) {
var builder = new UriBuilder(FacebookBaseGraphUri)
{
Query = string.Format("access_token={0}", accessToken)
};
var profileClient = new HttpClient();
var profileResponse = profileClient.Get(builder.Uri);
var formatter = new JsonValueMediaTypeFormatter();
formatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/javascript"));
var v = profileResponse.Content.ReadAs<JsonValue>(new[] {formatter});
return v["name"].ReadAs<string>();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment