public virtual async Task <HttpResponseMessage> GetAuthCallback() { var code = Request.GetQueryNameValuePairs().Where(nv => nv.Key == "code").Select(nv => nv.Value).FirstOrDefault(); var userId = Request.GetQueryNameValuePairs().Where(nv => nv.Key == "state").Select(nv => nv.Value).FirstOrDefault(); var stateObj = new JObject(); stateObj.Add("accessCode", code); stateObj.Add("userId", userId); var botSecret = ConfigurationManager.AppSettings[MicrosoftAppCredentials.MicrosoftAppPasswordKey]; var state = CipherHelper.Encrypt(stateObj.ToString(Newtonsoft.Json.Formatting.None), botSecret); var html = $@" <html> <head> <script src='https://statics.teams.microsoft.com/sdk/v1.0/js/MicrosoftTeams.min.js'></script> </head> <body> <script> microsoftTeams.initialize(); microsoftTeams.authentication.notifySuccess('{state}'); </script> </body> </html> "; var response = new HttpResponseMessage(); response.Content = new StringContent(html); response.Content.Headers.ContentType = new MediaTypeHeaderValue("text/html"); return(await Task.FromResult(response)); }
/// <summary> /// Handles state verification query for signin auth flow. /// </summary> /// <param name="activity">Incoming request from Bot Framework.</param> /// <param name="connectorClient">Connector client instance for posting to Bot Framework.</param> /// <returns>Task tracking operation.</returns> private static async Task <HttpResponseMessage> HandleStateVerificationQuery(Activity activity, ConnectorClient connectorClient) { SigninStateVerificationQuery stateVerifyQuery = activity.GetSigninStateVerificationQueryData(); var state = stateVerifyQuery.State; // Decrypt state string to get code and original userId var botSecret = ConfigurationManager.AppSettings[MicrosoftAppCredentials.MicrosoftAppPasswordKey]; var decryptedState = CipherHelper.Decrypt(state, botSecret); var stateObj = JsonConvert.DeserializeObject <JObject>(decryptedState); var code = stateObj.GetValue("accessCode").Value <string>(); var userId = stateObj.GetValue("userId").Value <string>(); // Verify userId var trustableUserId = activity.From.Id; if (userId != trustableUserId) { // Remove invalid user's cached credential (if any) userIdFacebookTokenCache.Remove(userId); // Issue a unauthorized message to clients Activity replyError = activity.CreateReply(); replyError.Text = "Unauthorized: User ID verification failed. Please try again."; await connectorClient.Conversations.ReplyToActivityWithRetriesAsync(replyError); return(new HttpResponseMessage(HttpStatusCode.Unauthorized)); } else { // Prepare FB OAuth request var fbAppId = ConfigurationManager.AppSettings["SigninFbClientId"]; var fbOAuthRedirectUrl = ConfigurationManager.AppSettings["SigninBaseUrl"] + "/auth/callback"; var fbAppSecret = ConfigurationManager.AppSettings["SigninFbClientSecret"]; var fbOAuthTokenUrl = "/v2.10/oauth/access_token"; var fbOAuthTokenParams = $"?client_id={fbAppId}&redirect_uri={fbOAuthRedirectUrl}&client_secret={fbAppSecret}&code={code}"; // Use access code to exchange FB token HttpResponseMessage fbResponse = await FBGraphHttpClient.Instance.GetAsync(fbOAuthTokenUrl + fbOAuthTokenParams); var tokenObj = await fbResponse.Content.ReadAsAsync <JObject>(); var token = tokenObj.GetValue("access_token").Value <string>(); // Update cache userIdFacebookTokenCache[userId] = token; // Send a thumbnail card with user's FB profile var card = await CreateFBProfileCard(token); Activity replyActivity = activity.CreateReply(); replyActivity.Attachments.Add(card); await connectorClient.Conversations.ReplyToActivityWithRetriesAsync(replyActivity); return(new HttpResponseMessage(HttpStatusCode.OK)); } }