Created
October 12, 2011 03:35
-
-
Save howarddierking/1280196 to your computer and use it in GitHub Desktop.
Web API Message Handler for processing Facebook OAuth2 auth code responses
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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