protected virtual async Task <string> GetAccessToken(string code) { var requestPrefix = Request.Scheme + "://" + Request.Host; var redirectUri = requestPrefix + Request.PathBase + Options.ReturnPath; var parts = new[] { "client_id=", Uri.EscapeDataString(Options.ClientId), "&client_secret=", Uri.EscapeDataString(Options.ClientSecret), "&code=", Uri.EscapeDataString(code), "&redirect_uri=", Uri.EscapeDataString(redirectUri) }; var request = CreateWebRequest(AccessTokenEndpoint); request.Method = "POST"; request.ContentType = "application/x-www-form-urlencoded"; request.Accept = "*/*"; var requestStream = await request.GetRequestStreamAsync(); using (var writer = new StreamWriter(requestStream)) { await writer.WriteAsync(string.Concat(parts)); } var response = await request.GetResponseAsync(); var responseStream = response.GetResponseStream(); if (responseStream == null) { return(null); } string body; using (var reader = new StreamReader(responseStream)) { body = await reader.ReadToEndAsync(); } var content = WebHelpers.ParseNameValueCollection(body); var accessToken = content["access_token"]; return(accessToken); }
protected override async Task <AuthenticationTicket> AuthenticateCore() { _logger.WriteVerbose("AuthenticateCore"); AuthenticationExtra extra = null; try { string code = null; string state = null; IDictionary <string, string[]> query = Request.GetQuery(); string[] values; if (query.TryGetValue("code", out values) && values != null && values.Length == 1) { code = values[0]; } if (query.TryGetValue("state", out values) && values != null && values.Length == 1) { state = values[0]; } extra = Options.StateDataHandler.Unprotect(state); if (extra == null) { return(null); } // OAuth2 10.12 CSRF if (!ValidateCorrelationId(extra, _logger)) { return(new AuthenticationTicket(null, extra)); } string tokenEndpoint = "https://graph.facebook.com/oauth/access_token"; string requestPrefix = Request.Scheme + "://" + Request.Host; string redirectUri = requestPrefix + Request.PathBase + Options.ReturnEndpointPath; string tokenRequest = "grant_type=authorization_code" + "&code=" + Uri.EscapeDataString(code) + "&redirect_uri=" + Uri.EscapeDataString(redirectUri) + "&client_id=" + Uri.EscapeDataString(Options.AppId) + "&client_secret=" + Uri.EscapeDataString(Options.AppSecret); WebRequest webRequest = WebRequest.Create(tokenEndpoint + "?" + tokenRequest); WebResponse webResponse = await webRequest.GetResponseAsync(); NameValueCollection form; using (var reader = new StreamReader(webResponse.GetResponseStream())) { string text = await reader.ReadToEndAsync(); form = WebHelpers.ParseNameValueCollection(text); } string accessToken = form["access_token"]; string expires = form["expires"]; string graphApiEndpoint = "https://graph.facebook.com/me"; webRequest = WebRequest.Create(graphApiEndpoint + "?access_token=" + Uri.EscapeDataString(accessToken)); webResponse = await webRequest.GetResponseAsync(); JObject user; using (var reader = new StreamReader(webResponse.GetResponseStream())) { user = JObject.Parse(await reader.ReadToEndAsync()); } var context = new FacebookAuthenticatedContext(Request.Environment, user, accessToken); context.Identity = new ClaimsIdentity( Options.AuthenticationType, ClaimsIdentity.DefaultNameClaimType, ClaimsIdentity.DefaultRoleClaimType); if (!string.IsNullOrEmpty(context.Id)) { context.Identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, context.Id, XmlSchemaString, Options.AuthenticationType)); } if (!string.IsNullOrEmpty(context.Username)) { context.Identity.AddClaim(new Claim(ClaimsIdentity.DefaultNameClaimType, context.Username, XmlSchemaString, Options.AuthenticationType)); } if (!string.IsNullOrEmpty(context.Email)) { context.Identity.AddClaim(new Claim(ClaimTypes.Email, context.Email, XmlSchemaString, Options.AuthenticationType)); } if (!string.IsNullOrEmpty(context.Name)) { context.Identity.AddClaim(new Claim("urn:facebook:name", context.Name, XmlSchemaString, Options.AuthenticationType)); } if (!string.IsNullOrEmpty(context.Link)) { context.Identity.AddClaim(new Claim("urn:facebook:link", context.Link, XmlSchemaString, Options.AuthenticationType)); } context.Extra = extra; await Options.Provider.Authenticated(context); return(new AuthenticationTicket(context.Identity, context.Extra)); } catch (Exception ex) { _logger.WriteError(ex.Message); } return(new AuthenticationTicket(null, extra)); }