DotNetOpenAuth Twitter Authenticaion Returning 401 Unauthorized - c#

I'm starting to tear my hair out with Twitter and trying to signin a user!!! I have Facebook, Google, OpenId all working fine, just Twitter being a PAIN.
I am constantly getting 401 Unauthorized when I try to run my code and for the life of me cannot figure out why.
I have created a twitter client and and I'm using it with the InMemoryTokenManager from the DotNetOpenAuth sample solution. My Twitter client is here
public class TwitterClient
{
private string UserName { get; set; }
private static readonly ServiceProviderDescription ServiceDescription =
new ServiceProviderDescription
{
RequestTokenEndpoint = new MessageReceivingEndpoint(
"https://api.twitter.com/oauth/request_token",
HttpDeliveryMethods.GetRequest |
HttpDeliveryMethods.AuthorizationHeaderRequest),
UserAuthorizationEndpoint = new MessageReceivingEndpoint(
"https://api.twitter.com/oauth/authorize",
HttpDeliveryMethods.GetRequest |
HttpDeliveryMethods.AuthorizationHeaderRequest),
AccessTokenEndpoint = new MessageReceivingEndpoint(
"https://api.twitter.com/oauth/access_token",
HttpDeliveryMethods.GetRequest |
HttpDeliveryMethods.AuthorizationHeaderRequest),
TamperProtectionElements = new ITamperProtectionChannelBindingElement[] { new HmacSha1SigningBindingElement() },
};
IConsumerTokenManager _tokenManager;
public TwitterClient(IConsumerTokenManager tokenManager)
{
_tokenManager = tokenManager;
}
public void StartAuthentication()
{
var request = HttpContext.Current.Request;
using (var twitter = new WebConsumer(ServiceDescription, _tokenManager))
{
var callBackUrl = new Uri(request.Url.Scheme + "://" + request.Url.Authority + "/Members/TwitterCallback");
twitter.Channel.Send(
twitter.PrepareRequestUserAuthorization(callBackUrl, null, null)
);
}
}
public bool FinishAuthentication()
{
using (var twitter = new WebConsumer(ServiceDescription, _tokenManager))
{
var accessTokenResponse = twitter.ProcessUserAuthorization();
if (accessTokenResponse != null)
{
UserName = accessTokenResponse.ExtraData["screen_name"];
return true;
}
}
return false;
}
}
And I have the following in the constructor of my MembersController which is instantiating the InMemoryTokenManager with the correct credentials
_tokenManager = new InMemoryTokenManager(ConfigUtils.GetAppSetting("TwitterAppId"), ConfigUtils.GetAppSetting("TwitterAppSecret"));
And my two Actions are
public ActionResult LogonTwitter()
{
var client = new TwitterClient(_tokenManager);
client.StartAuthentication();
return null;
}
public ActionResult TwitterCallback()
{
var client = new TwitterClient(_tokenManager);
if (client.FinishAuthentication())
{
return new RedirectResult("/");
}
// show error
return View("LogOn");
}
The error appears in the StartAuthentication() in my TwitterClient. As soon as it calls this line
twitter.Channel.Send(
twitter.PrepareRequestUserAuthorization(callBackUrl, null, null)
);
I get the following error
Error occurred while sending a direct message or getting the response.
Inner Exception: The remote server returned an error: (401) Unauthorized.
Anyone got any advice? I have spent most of yesterday and this morning trying to sort this. All the online examples I have tried also seem to get 401 Unauthorized back? Is there a known issue with DotNetOpenAuth and Twitter?
Any help very much appreciated.

I can't remember the exact terminology but have you set up a callback URL in the twitter app (as well as in the code)? I've had similar problems recently, even when developing locally I believe you need to set that value, even if its just a placeholder

Related

facebook Marketing API error 803 c# [duplicate]

I am trying to get education detail and work description of user from facebook. I login successfully and get Access token. But I am unable to get details I want
Code I am using for it :-
public void getUserExpandEducation() {
new GraphRequest(
AccessToken.getCurrentAccessToken(),
"/{education-experience-id}", //"/{user_education_history}",//
null,
HttpMethod.GET,
new GraphRequest.Callback() {
public void onCompleted(GraphResponse response) {
Log.d("fb response",response.toString());
}
}
).executeAsync();
}
can anyone please reply
I am getting error (#803) Some of the aliases you requested do not exist: {education-experience-id}
Finally I got full work and education detail by this code:
GraphRequest request = GraphRequest.newMeRequest(
accessToken,
new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(
JSONObject object,
GraphResponse response) {
FirstNameSocial = object.optString("first_name");
LastNameSocial = object.optString("last_name");
GenderSocial = object.optString("gender");
EmailSocial = object.optString("email", "");
id = object.optString("id");
if (!EmailSocial.equals("")) {
login_type = Config.Login_Type_facebook;
callAPI(EmailSocial, id, "");
} else {
Toast.makeText(getApplicationContext(), "Permision Denied", Toast.LENGTH_LONG)
.show();
}
}
});
Bundle parameters = new Bundle();
parameters.putString("fields", "id,name,email,birthday,gender,first_name,last_name,picture,education,work");
request.setParameters(parameters);
request.executeAsync();
Might help someone !
Happy coding :)
Make sure you authorized with that permission: user_education_history
API call to get a list of education IDs: https://developers.facebook.com/tools/explorer/?method=GET&path=me%3Ffields%3Deducation
In your code, you need to replace the following string with one of the resulting education IDs: {education-experience-id}
For example:
new GraphRequest(
AccessToken.getCurrentAccessToken(),
"/12345",
null,
HttpMethod.GET,
new GraphRequest.Callback() {
public void onCompleted(GraphResponse response) {
Log.d("fb response",response.toString());
}
}
).executeAsync();

Microsoft Translator service on Azure (how to make it work?)

I've been using Microsoft Translator service from my C# applications for a while. However, since I created my Azure subscription, the function below keeps returning: "Could not translate". As I understand, now I need to use Microsoft Translator somehow differently. I searched the Web actively but could not find any working examples or/and similar questions. Below I provide my code that used to work but now it does not:
public static String TranslateToEnglish(String str)
{
return Translate(GetTokenWrapper(), str, "en");
}
public static String GetTokenWrapper()
{
AdmAccessToken admToken;
AdmAuthentication admAuth = new AdmAuthentication("..", "..");
admToken = admAuth.GetAccessToken();
return "Bearer " + admToken.access_token;
}
public static String Translate(HttpRequestMessageProperty httpRequestProperty,string authToken, string what, string to)
{
// Add TranslatorService as a service reference, Address:http://api.microsofttranslator.com/V2/Soap.svc
LanguageServiceClient client = new LanguageServiceClient();
HttpRequestMessageProperty httpRequestProperty = new HttpRequestMessageProperty();
httpRequestProperty.Method = "POST";
httpRequestProperty.Headers.Add("Authorization", authToken);
using (OperationContextScope scope = new OperationContextScope(client.InnerChannel))
{
OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty;
string sourceText = what;
string translationResult;
try
{
translationResult = client.Translate("", sourceText, "", to, "text/plain", "general", "");
}
catch(Exception ex) { return ex.ToString(); }
return translationResult;
}
You use Microsoft translator in exactly the same way on Azure as you did before the move. The only difference is you need to use the Azure key and get a token from the new end point for tokens.
This shows you how to get an azure token:
https://github.com/MicrosoftTranslator/GetAzureToken

Verified IPN with empty data

I will try to get this straight.
I use integrated PayPal Adaptive Payments and implemented IPN, using ASP.NET MVC and C#. I tried the IPN simulator and everything is fine. I got the call and processed the data. The problem is when it comes to payment with the test accounts I made. The payment succeeds and I receive "Verified", but there is not data about the payer or the transaction, or anything. In my PayPal account all transactions are successful. I can post my code, but I don't see how this will help. The thing is that it works perfectly well when sending the IPN from the simulator, but it is not working properly when sandbox sends the IPN after a successful payment.
Its hard to tell exactly what your problem might be. I've never used their test tool but here's some code that is working with both Sandbox and production versions. Note that the original POST data actually has the transaction information. In my case I only care about the data in the memo field. MVC binding ensures its populated.
One more thing you might want to check... when logged into PayPal you can see the IPN history and see the content of each message sent. Perhaps that is the problem.
public class IPNController : Controller
{
private readonly ILogger _logger;
private readonly IPaymentManager _paymentManager;
private readonly IIdentityManager _identityManager;
public IPNController(ILogger logger, IPaymentManager paymentManager, IIdentityManager identityManager)
{
_logger = logger;
_paymentManager = paymentManager;
_identityManager = identityManager;
}
[HttpPost]
public HttpStatusCodeResult Receive(PayPalCheckoutInfo info)
{
//Fire and forget verification task
Task.Run(() => VerifyTask(Request, info.Memo));
//Reply back a 200 code
return new HttpStatusCodeResult(HttpStatusCode.OK);
}
private void VerifyTask(HttpRequestBase ipnRequest, string memo)
{
try
{
var verificationRequest = (HttpWebRequest)WebRequest.Create(Application.PayPalIPNUrl);
//Set values for the verification request
verificationRequest.Method = "POST";
verificationRequest.ContentType = "application/x-www-form-urlencoded";
var param = Request.BinaryRead(ipnRequest.ContentLength);
var strRequest = Encoding.ASCII.GetString(param);
//Add cmd=_notify-validate to the payload
strRequest = "cmd=_notify-validate&" + strRequest;
verificationRequest.ContentLength = strRequest.Length;
//Attach payload to the verification request
var streamOut = new StreamWriter(verificationRequest.GetRequestStream(), Encoding.ASCII);
streamOut.Write(strRequest);
streamOut.Close();
//Send the request to PayPal and get the response
var streamIn = new StreamReader(verificationRequest.GetResponse().GetResponseStream());
var verificationResponse = streamIn.ReadToEnd();
streamIn.Close();
var transactionIdentifier = memo.Split(':')[1].Trim();
//_logger.Info($"strRequest: {strRequest}");
//_logger.Info($"verificationResponse: {verificationResponse}");
// We receive 2 messages from PayPal. Only complete this for one...
if (verificationResponse.Equals("VERIFIED"))
{
if (strRequest.Contains("payment_type=instant"))
{
_paymentManager.CompleteTransaction(transactionIdentifier);
_logger.Info($"IPNController.VerifyTask. Payment marked as 'Paid'. transactionIdentifier={transactionIdentifier}");
}
}
else
{
_logger.Warn($"IPNController.VerifyTask. A non-verified request was received. transactionIdentifier={transactionIdentifier}");
}
}
catch (Exception ex)
{
_logger.Error("IPNController.VerifyTask", ex);
}
}
}
public class PayPalCheckoutInfo
{
public string Memo { get; set; }
//mc_gross=6.15
//protection_eligibility=Ineligible
//payer_id=ZJ93C8BT7HYE4
//tax=0.00
//payment_date=21:09:26 Jan 26, 2016 PST
//payment_status=Completed
//charset=windows-1252
//first_name=Sandbox
//mc_fee=0.48
//notify_version=3.8
//custom=
//payer_status=verified
//business=developer+application #trytn.com
//quantity= 0
//verify_sign = A8RQ0F8gkUzMctcqZ4r9aZzwD7JUA2ltLngw8Dny8kkzavsf9M8bRfZ3
// payer_email = developer + merchant#trytn.com
//memo= Trytn
//txn_id = 52W35468KJ348570R
//payment_type= instant
//payer_business_name = Sandbox Merchant's Test Store
//last_name= Merchant
//receiver_email = developer + application#trytn.com
//payment_fee= 0.48
//receiver_id = VMLFKLT4VDZQL
//txn_type = web_accept
//item_name =
//mc_currency = USD
//item_number =
//residence_country = US
//test_ipn = 1
//transaction_subject =
//payment_gross = 6.15
//ipn_track_id = 245bfe354148e
}
Original Source: https://github.com/paypal/ipn-code-samples/pull/31/files

Missing Authorization header in Basic authentication

I used following code to implement Basic Authentication filter in my ASP.Net MVC app. everything is working good in local machine while it's not working in production server and it keeps prompting login box because Request.Headers["Authorization"] is null.
I used fiddler to get headers for this request and Authorization header was there with expected values. I have no idea why Request.Headers["Authorization"] is always null :|
I also created a new project only with this filter and one controller and published in server, guess what !? it's working...
public class RequireBasicAuthenticationAttribute : ActionFilterAttribute
{
public string BasicRealm { get; set; }
protected string Username { get; set; }
protected string Password { get; set; }
public RequireBasicAuthenticationAttribute()
{
this.Username = System.Configuration.ConfigurationManager.AppSettings["ProtectedUsername"];
this.Password = System.Configuration.ConfigurationManager.AppSettings["ProtectedPassword"];
}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var req = filterContext.HttpContext.Request;
var auth = req.Headers["Authorization"];
auth.LogText();
if (!string.IsNullOrEmpty(auth))
{
var cred = System.Text.ASCIIEncoding.ASCII.GetString(Convert.FromBase64String(auth.Substring(6))).Split(':');
var user = new { Name = cred[0], Pass = cred[1] };
if (Username.Equals(user.Name, StringComparison.InvariantCultureIgnoreCase) && Password.Equals(user.Pass)) return;
}
var res = filterContext.HttpContext.Response;
res.StatusCode = 401;
res.AddHeader("WWW-Authenticate", String.Format("Basic realm=\"{0}\"", BasicRealm ?? "bimeh-takmili"));
res.End();
}
}
Just looking at your code I don't see how it runs at all, production or otherwise.
I would suggest it's throwing an error that your code is swallowing since the code below closes the response and then tries to call the base method.
public override void ExecuteResult(ControllerContext context)
{
if (context == null) throw new ArgumentNullException("context");
// this is really the key to bringing up the basic authentication login prompt.
// this header is what tells the client we need basic authentication
var res = context.HttpContext.Response;
res.StatusCode = 401;
res.AddHeader("WWW-Authenticate", "Basic");
res.End();
base.ExecuteResult(context);
}
You cant do this, the code will throw an error:
Server cannot set status after HTTP headers have been sent.
And since it's throwing an error (i think) and being bounced around, it might not be output a 401 status response. The "WWW-Authenticate" header is still being sent however which is why your getting a dialog.
The credentials dialog is popped a when "WWW-Authenticate" is detected but it will only send back an Authorization header in the request if it received a 401 status from the last response.
So if you drop:
base.ExecuteResult(context);
from your code, what happens?
Edit:
Actually dropping
res.End();
would be the way to go. Duh.

Facebook permission error

public Form1()
{
InitializeComponent();
// The application key of the Facebook application used
fbService.ApplicationKey = "XXXXXXXXXXX";
// Add all needed permissions
List<Enums.ExtendedPermissions> perms = new List<Enums.ExtendedPermissions>
{
Enums.ExtendedPermissions.none
};
fbService.ConnectToFacebook(perms); //error here (The given key was not present in the dictionary.)
}
I mention the error where I get the error , as am new to facebook api and specially new to c# any explained answer is appriciated
Thank you
Use the static method on FacebookClient like this:
FacebookClient.SetDefaultHttpWebRequestFactory(uri => {
var request = new HttpWebRequestWrapper((HttpWebRequest)WebRequest.Create(uri));
request.Proxy = ......; // normal .net IWebProxy
return request;
});
See this answer also: Facebook SDK Proxy setting C#

Categories