public async Task <ActionResult <AuthenticationResponse> > GetTwitterJWT([FromBody] TwitterRequestTokenResponse twitterRequestTokenResponse) { // Step 1 : initializing variables string token = string.Empty; var httpClient = _httpClientFactory.CreateClient(); // Step 2 : getting keys from appsettings.json var consumerKey = _configuration["Authentication:Twitter:ConsumerKey"]; var consumerSecrete = _configuration["Authentication:Twitter:ConsumerSecrete"]; // Step 3 : requesting oauth_token & oauth_token_secrete var client = new RestClient("https://api.twitter.com"); // Note NO /1 client.Authenticator = OAuth1Authenticator.ForAccessToken( consumerKey, consumerSecrete, twitterRequestTokenResponse.OAuthToken, twitterRequestTokenResponse.OAuthTokenSecrete, twitterRequestTokenResponse.OAuthVerifier ); var request = new RestRequest("/oauth/access_token", Method.Post); var response = await client.ExecuteAsync(request); var qs = HttpUtility.ParseQueryString(response.Content); var _token = qs["oauth_token"]; var _tokenSecret = qs["oauth_token_secret"]; // Step 4 : passing oauth_token & oauth_token_secrete to Twitter API to get email address of the user var emailAddress = await GetTwitterEmailAddress(_token, _tokenSecret); // Step 5 : try to find the user in the database or create a new account var loggedInUser = await GetUserByEmailAddress(emailAddress); // Step 6 : generate the token if (loggedInUser == null) { loggedInUser = await CreateExternalUser(emailAddress); } token = GenerateJwtToken(loggedInUser); httpClient.Dispose(); // Step 7 : returning the token back to the client return(await Task.FromResult(new AuthenticationResponse() { Token = token })); }
/* * This method conducts the request to Twitter's APIs. */ public TwitterRequestTokenResponse ExecuteAuthentication() { /* * The response object we're expecting from Twitter. This is a custom object * defined in a class below. */ TwitterRequestTokenResponse parsedResponse = null; try { string response = null; string error = null; using (var client = new WebClient()) { /* * Using a try-catch within the Using statement should ensure that the WebClient is disposed. * * WebClient is an easy, but possibly not optimal, solution here. Not optimal because * it doesn't provide any opportunity to catch the response before it throws an error. * Hence the try-catch. * * Ideally, these calls would contain logic to catch the response code (400, 401, 404, 200, etc.) * and react with messaging to the visitor accordingly. */ try { client.Headers["Authorization"] = this.GetAuthorizationString(); response = client.UploadString(this.TwApiUrl, this.TwMethod, ""); } catch (Exception ex) { EkException.LogException(ex); error = ex.Message; } } /* * The constructor for the Response object will parse the string. */ parsedResponse = new TwitterRequestTokenResponse(response); } catch (Exception ex) { EkException.LogException(ex); } return(parsedResponse); }
/// <summary> /// Retrieves a Twitter request token for the Twitter Request token auth flow /// </summary> /// <param name="options">The options for this request</param> /// <returns></returns> public async Task <string> GetTwitterRequestTokenAsync(RequestOptions options = null) { options = options ?? RequestOptions.CreateFromDefaults(ApiClient.Config); options.UseAccessToken = false; RestResponse response = await ApiClient.SendJsonAsync( "POST", "oauth/token", new { grant_type = "request_token", provider = "twitter" }, options).ConfigureAwait(false); TwitterRequestTokenResponse auth = await response.ReadAsJsonAsync <TwitterRequestTokenResponse>(ApiClient.Config).ConfigureAwait(false); return(auth.RequestToken); }
public async Task <string> GetTwitterJWTAsync(TwitterRequestTokenResponse twitterRequestTokenResponse) { using var httpMessageResponse = await _httpClient.PostAsJsonAsync("user/getTwitterjwt", twitterRequestTokenResponse); return((await httpMessageResponse.Content.ReadFromJsonAsync <AuthenticationResponse>()).Token); }
/* * The Page_Load logic here handles */ protected void Page_Load(object sender, EventArgs e) { /* * Detect if the user is logged in. This is the most efficient way to go about * it as it employs a static option. You could call upon the UserManager defined * above, but that may cause it to initialize unnecessarily. */ if (Ektron.Cms.Framework.Context.UserContextService.Current.IsLoggedIn) { uxAuthenticationViews.SetActiveView(uxLogoutView); } else { /* * Ensure the login view is set. It should by default, but it's best to specify * it explicitly in case of inadvertent postbacks. */ uxAuthenticationViews.SetActiveView(uxLoginView); /* * I'm not going to perform checks against the querystring until I know it has values. */ if (Request.QueryString.Count > 1) { /* * Try to get the values from the querystring. * * These are the values that are returned by Twitter when the user has successfully * authenticated. Not to worry, we're not going to assume these values are valid * for authentication without some double-checking. */ string oAuthToken = Request.QueryString["oauth_token"]; string oAuthVerifier = Request.QueryString["oauth_verifier"]; /* * Make sure the parameters have values. :) */ if (!string.IsNullOrEmpty(oAuthToken) && !string.IsNullOrEmpty(oAuthVerifier)) { /* * Get the original request token values out of the Session. */ TwitterRequestTokenResponse originalResponse = (TwitterRequestTokenResponse)Session["TwitterAuthValues"]; /* * Compare the token recieved in the querystring with the Request Token API. * * If they're the same, then you can trust that the visitor is just arrived * from your authentication request. */ if (oAuthToken == originalResponse.OAuthToken) { /* * Authentication successful! * * Now you need to use this information to get some information about the visitor * who just authenticated to your site. In everything we've done so far, we still * don't know the visitor's screen name or Twitter ID, for example. * * In addition, we can't make any requests on behalf of that user. The app that I've * registered for this sample application is read-only. What I can do with that is * read the profile and tweets of this user. I may be able to use that for some * personalization. For example, I may want to know whether this visitor has mentioned * my company by name or used any of the hashtags we're interested in. * * In order to request that information, I need another token, which I will also get * in the following request. As mentioned above, I'm only making use of the visitor's * screen name and user id below, not the token. And as such, this code does not * show you how to store that token or use it in Twitter's APIs. */ /* * To kick things off, I'll create a new access token request. This is a custom class * defined below which will hold data and make calculations specifically for this request. * * The request will make use of the newly received token and verifier that we got out * of the querystring. I'm passing them to the new object as it's initialized. */ var AccessRequest = new TwitterAccessTokenRequest(oAuthToken, oAuthVerifier); /* * Make the request. The workings of this method are described within its parent class * below. It returns a response which contains an access token (to get read-only data), * secret, as well as the visitor's Twitter Screen Name and User ID. */ var AccessResponse = AccessRequest.ExecuteAccessTokenRequest(); /* * Make sure it didn't incur any errors. If so, respond accordingly. */ if (!string.IsNullOrEmpty(AccessResponse.ErrorMessage)) { uxLoginError.InnerText = string.Format("We were unable to get an authentication token from Twitter. Error: {0}", AccessResponse.ErrorMessage); uxLoginError.Visible = true; } else { /* * At this point, all has gone well. The user has granted permissions and we were able * to verify their identity using Twitter's APIs. First, we attempt to login the user * with the Authentication ID (defined as a private global above) and their Twitter * User ID. * * The User ID is used here rather than their Screen Name because a Twitter user can * alter their screen name at any time, but not their ID. As long as you use their ID * then the visitor can alter their screen name at any time, yet still be albe to login * to your site. */ /* * Establish initial user object. Set to null for now. If login is successful, then the * object will be given a value. */ UserData loggedInUser = null; try { /* * Using the Authentication Type ID and Authentication User ID is the only method for * logging a user in without having a password. Hence, any 3rd party authentication * system used in your application should have a unique Type ID. * * I arbitrarily chose 6000 to represent Twitter. As I add authentication schemes, I may * increment that value by 100 for each. E.g., Facebook = 6100, Google = 6200. These * are not standard. They are chosen by the developer. */ loggedInUser = UserCRUD.Login(TwitterAuthenticationId, AccessResponse.UserId); } catch { } /* * If the login above fails, the user object will still be null. It's via this check that we will * know whether the login is successful or not. Null = unsuccessful. * * For attempts that are authenticated against twitter, but don't have a user account within the * application, I chose to create their account automatically. You may, instead, choose * to redirect the user to a form to establish a more complete profile before actually * adding the user to the system. */ if (loggedInUser == null) { /* * Establish the new, empty user object. */ var newUser = new UserData(); /* * This setting is often overlooked - so make sure you set it or everyone who signs in via * Twitter will become CMS Authors. Yikes! */ newUser.IsMemberShip = true; /* * I'm using the visitor's Twitter Screen Name as their Username and Display Name within Ektron. * * These values must be unique. In my case, it helps to prefix their names with an @ symbol * in order to more closely align them with Twitter. :) */ newUser.Username = string.Format("@{0}", AccessResponse.ScreenName); newUser.DisplayName = newUser.Username; /* * Authentication type id must be the same for every user authenticated against Twitter. */ newUser.AuthenticationTypeId = TwitterAuthenticationId; /* * In Twitter, screen names can change, but User IDs cannnot. Use the User ID for this * so the user can change their Twitter screen name but still log in to your site. */ newUser.AuthenticationUserId = AccessResponse.UserId; /* * Random, meaningless password. Ektron provides the method below for generating a random password * based on the validation expression. */ newUser.Password = UserCRUD.GetRandomPasswordforDefaultRegex(); /* * The twitter methods used so far do not provide a reliable first and last name. Some Twitter * users choose to enter these, but many do not. You may use another API to request this information * from Twitter or, because the fields are required in Ektron, do as I have done and enter * placeholder values. */ newUser.FirstName = "not set"; newUser.LastName = "not set"; /* * Time Zone is a required custom property in any default Ektron installation. You may have this or * other required fields for your users - develop accordingly. * * There are ways to *guess* at a user's current time zone that are beyond the scope of this sample. * Ideas include: * * Requesting the information with JavaScript in a previous page load * * Using GeoIP data to get the time zone * * The GetCustomPropertyList method below gets the full set of properties with their default values. * Simply set those you need and then assign the list to the new user object. */ var customProps = UserCRUD.GetCustomPropertyList(); customProps["Time Zone"].Value = "Eastern Standard Time"; newUser.CustomProperties = customProps; /* * Add the new user to the CMS. */ newUser = UserCRUD.Add(newUser); /* * Login the new user. */ UserCRUD.Login(newUser.AuthenticationTypeId, newUser.AuthenticationUserId); } /* * Use a Redirect here to ensure Ektron's ECM cookie is properly set as well as to remove any lingering * postback and unneeded viewstate data. * * Also removing the querystring, which contained values used to verify the authentication of the * current user. */ Response.Redirect(Request.RawUrl.Split('?')[0]); } } } } } }