I stuсk on using DNOA library for twitter 1.1 api
enter code here
I am trying to call users/show.json api
protected override AuthenticationResult VerifyAuthenticationCore(AuthorizedTokenResponse response)
{
string accessToken = response.AccessToken;
string str2 = response.ExtraData["user_id"];
string userName = response.ExtraData["screen_name"];
Uri location = new Uri("https://api.twitter.com/1.1/users/show.json?user_id=" + str2);
MessageReceivingEndpoint profileEndpoint = new MessageReceivingEndpoint(location, HttpDeliveryMethods.GetRequest | HttpDeliveryMethods.AuthorizationHeaderRequest);
HttpWebRequest request = base.WebWorker.PrepareAuthorizedRequest(profileEndpoint, accessToken);
Dictionary<string, string> dictionary = new Dictionary<string, string>();
dictionary.Add("accesstoken", accessToken);
try
{
using (WebResponse wresponse = request.GetResponse())
{
var str = Utilities.ProcessResponse(wresponse);
var json = JObject.Parse(str);
dictionary.AddNotEmpty("name", json.Value<string>("name"));
dictionary.AddNotEmpty("location", json.Value<string>("location"));
dictionary.AddNotEmpty("description", json.Value<string>("description"));
dictionary.AddNotEmpty("url", json.Value<string>("url"));
}
}
catch (Exception)
{
}
return new AuthenticationResult(true, base.ProviderName, str2, userName, dictionary);
}
This what is sends to twitter
GET https://api.twitter.com/1.1/users/show.json?user_id=2193937074 HTTP/1.1
Authorization: OAuth oauth_token="2193937074-cgmZbmJIIb75f7MkQgbdjuvQaen2xzM1WFXXC7G",oauth_consumer_key="XVCgN3fkwzTGgeSm1FBa1Q",oauth_nonce="93UjjRkP",oauth_signature_method="HMAC-SHA1",oauth_signature="YzfXzU3VeEI9xl2SfuknPB33%2FiM%3D",oauth_version="1.0",oauth_timestamp="1389265955"
Host: api.twitter.com
The responce is
HTTP/1.1 401 Unauthorized
content-length: 63
content-type: application/json; charset=utf-8
date: Thu, 09 Jan 2014 11:12:36 UTC
server: tfe
set-cookie: guest_id=v1%3A138926595613849064; Domain=.twitter.com; Path=/; Expires=Sat, 09-Jan-2016 11:12:36 UTC
strict-transport-security: max-age=631138519
{"errors":[{"message":"Could not authenticate you","code":32}]}
The dev.twitter's OAuth tool shows the valid sample of signed header:
GET https://api.twitter.com/1.1/users/show.json?user_id=2193937074 HTTP/1.1
Authorization: OAuth oauth_consumer_key="XVCgN3fkwzTGgeSm1FBa1Q", oauth_nonce="dbf6f6c1aa6dc226de25265da3d63167", oauth_signature="K3Qfyc9qANFgckQNyqsaDWCnh%2BY%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1389266681", oauth_token="2193937074-cgmZbmJIIb75f7MkQgbdjuvQaen2xzM1WFXXC7G", oauth_version="1.0"
Host: api.twitter.com
It loook's like the main difference is in length of the oauth_nonce?
DNOA - oauth_nonce="93UjjRkP"
OAuth tool - oauth_nonce="dbf6f6c1aa6dc226de25265da3d63167"
I solved the problem.
The main problem is how the signature is created, the TokenSecret is excluded from it's forming. The core of the this behavior is the AuthenticationOnlyCookieOAuthTokenManager manager that is used inside the base DotNetOpenAuth.AspNet.Clients.TwitterClient class.
public class AuthenticationOnlyCookieOAuthTokenManager : IOAuthTokenManager
{
...
public virtual void ReplaceRequestTokenWithAccessToken(string requestToken, string accessToken, string accessTokenSecret)
{
HttpCookie cookie = new HttpCookie("OAuthTokenSecret") {
Value = string.Empty, //<<< now it's empty
Expires = DateTime.UtcNow.AddDays(-5.0)
};
this.Context.Response.Cookies.Set(cookie);
}
...
}
It's just remove the tokenSecret;
The solution is to use the DotNetOpenAuth.AspNet.Clients.InMemoryOAuthTokenManager class. So you need just derive from OAuthClient and implement proper constructor:
public class TwitterClient : DotNetOpenAuth.AspNet.Clients.OAuthClient
{
protected TwitterClient(string appKey, string appSecret) :
base ("twitter",
new DotNetOpenAuthWebConsumer(
TwitterServiceDescription,
new InMemoryOAuthTokenManager(appKey, appSecret)))
{ }
...
}
Also have found the familiar post Custom OAuth client in MVC4 / DotNetOpenAuth - missing access token secret
Related
I am using MockMVC to test the JWT Token/authentication and I am having some trouble understanding why the JSON cannot be read.
This is the test that Ive written:
#SpringBootTest
#AutoConfigureMockMvc
public class JwtSecurityTest {
#Autowired
private MockMvc mockMvc;
#Test
public void existentUserCanGetTokenAndAuthentication() throws Exception {
String username = "user";
String password = "pass";
String body = "{"username":"" + username + "","password":"" + password + ""}";
MvcResult result = mockMvc.perform(post("http://localhost:8080/login/authenticate")
.contentType(MediaType.APPLICATION_JSON)
.content(body))
.andDo(MockMvcResultHandlers.print())
.andReturn();
String token = result.getResponse().getContentAsString();
mockMvc.perform(MockMvcRequestBuilders.get("http://localhost:8080/kund")
.contentType(MediaType.APPLICATION_JSON)
.header("Authorization", "Bearer " + token))
.andExpect(status().isOk());
}
And the error I get is:
MockHttpServletResponse:
Status = 200
Error message = null
Headers = [Content-Type:"application/json", X-Content-Type-Options:"nosniff", X-XSS-Protection:"1; mode=block", Cache-Control:"no-cache, no-store, max-age=0, must-revalidate", Pragma:"no-cache", Expires:"0", X-Frame-Options:"DENY"]
Content type = application/json
Body = {"jwt":"eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJzbHkiLCJleHAiOjE2NTMwODM5NDMsImlhdCI6MTY1MzA0Nzk0M30.V5qqIRzlAtkXEK_OcFbiIlEaOdej3oyGFMy6Aw57ZB8"}
Forwarded URL = null
Redirected URL = null
Cookies = []
io.jsonwebtoken.MalformedJwtException: Unable to read JSON value: ?^?[????M
I find it weird because in the body, we can clearly see that the token looks good.
I am using MVC framework to make POST request to OneLogin API to get JWT. I am getting a 401 unauthorized message back at my PostAsync call in the code below.
Error look like following
StatusCode: 401, ReasonPhrase: 'Unauthorized', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
{
Pragma: no-cache
Cache-Control: no-store, no-cache
Date: Wed, 17 Jun 2020 04:21:23 GMT
Set-Cookie: ol_oidc_canary_30=false; path=/; domain=.onelogin.com
X-Powered-By: Express
Content-Length: 77
Content-Type: application/json; charset=utf-8
}
Am i missing any parameters. I registered my localhost on One login dev account. Is there any setting there i need to update or change?
public async Task<OidcTokenResponse> ProcessToken(string code, string clientSec)
{
string authorityToken = OneLoginAuthorityToken;
var formData = new System.Net.Http.FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("code", code),
new KeyValuePair<string, string>("client_id", OneLoginClientID),
new KeyValuePair<string, string>("client_secret", clientSec),
new KeyValuePair<string, string>("grant_type", "authorization_code"),
});
using (var client = new System.Net.Http.HttpClient())
{
const SslProtocols _Tls12 = (SslProtocols)0x00000C00;
const System.Net.SecurityProtocolType Tls12 = (System.Net.SecurityProtocolType)_Tls12;
System.Net.ServicePointManager.SecurityProtocol = Tls12;
var res = await client.PostAsync(authorityToken, formData);
var json = await res.Content.ReadAsStringAsync();
var tokenReponse = Newtonsoft.Json.JsonConvert.DeserializeObject<OidcTokenResponse>(json);
return tokenReponse;
}
}
You need to send the redirect_uri again in this message - it is a security feature of the authorization code flow.
Also worth tracing the messages with a tool such as Fiddler to ensure that the messages sent over the wire are what you'd expect.
See steps 4 and 8 of my messages write up for something to compare against.
I create json object and assign it to a StringContent of my HttpResponseMessage instance. Everything works fine when I call the Web API action, the result is 200, the content-length is how it should be, but how to find the content itself, where is the json? What I get in the browser and in Postman is this:
StatusCode: 200, ReasonPhrase: 'OK', Version: 1.1, Content: System.Net.Http.StringContent, Headers:
{
Content-Type: application/json
}
Why is this instead of my json string?
Content: System.Net.Http.StringContent
If what you are trying to achieve is to return a valid JSON response, then this is the way to go in Asp.Net MVC
public ActionResult HttpResponseMessage()
{
var oJSON = new { url = "path_to_file", hash = "aaaaaaaaaaaaaaaaa" };
return Json(oJSON, JsonRequestBehavior.AllowGet);
}
Response headers as seen by Postman:
Cache-Control →private
Content-Length →49
Content-Type →application/json; charset=utf-8
Date →Fri, 26 Oct 2018 13:31:44 GMT
Server →Microsoft-IIS/10.0
X-AspNet-Version →4.0.30319
X-AspNetMvc-Version →5.2
X-Powered-By →ASP.NET
X-SourceFiles →=?UTF-8?B?RTpcRXhhbSA3MCA0ODdcNzA0ODdcTVZDUm91dGVzXEhvbWVcSHR0cFJlc3BvbnNlTWVzc2FnZQ==?=
Response body as seen by Postman
{"url":"path_to_file","hash":"aaaaaaaaaaaaaaaaa"}
I'm writing a simple desktop application to get information from QuickBooks(developer account using demo account(UK) data) and in this regard I've been able to go past the OAuth flow. However, I've not been able to get the basic company information
The below is a capture of the Fiddler request and response:
GET https://quickbooks.api.intuit.com/v3/company/123145829830639/companyInfo/123145829830639 HTTP/1.1
Authorization: oauth_token="****", oauth_nonce="z4x0a196", oauth_consumer_key="****", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1499283607", oauth_version="1.0", oauth_signature="EGw6Ty%2BKFAawrH1%2FSxQuFwaMcEo%3D"
Content-Type: application/json
Host: quickbooks.api.intuit.com
The generation of the header is similar to https://developer.intuit.com/v2/apiexplorer?apiname=V3QBO#?id=CompanyInfo but I end up getting the following response(Fiddler partial response) based on the request
intuit_tid: gw-c4e19f89-df78-42a5-ae7e-216187421143
Set-Cookie: JSESSIONID=21BF1FFEE48B39538E82485FD25C4280.c51-pprdsbxas901; Path=/; Secure; HttpOnly
QBO-Version: 1706.912
ErrorCode: 100
ErrorCause: AuthenticationErrorGeneral: SRV-110-Authentication Failure , statusCode: 401
Message: General Authentication Error
The code to access company information is as below:
string companyInfo = String.Format("company/{0}/companyInfo/{0}", authenticator.OAuthProfile.realmId);
string ciUrl = BASE_URL + companyInfo; //https://quickbooks.api.intuit.com/v3/
var sb = new System.Text.StringBuilder();
sb.AppendFormat("oauth_token=\"{0}\", oauth_nonce=\"{1}\", oauth_consumer_key=\"{2}\", oauth_signature_method=\"HMAC-SHA1\", oauth_timestamp=\"{3}\", oauth_version=\"1.0\", oauth_signature=\"{4}\"",
Manager.UrlEncode(_token),
Manager.UrlEncode(_nonce),
Manager.UrlEncode(_consumer_key),
Manager.UrlEncode(_timestamp),
Manager.UrlEncode(_signature));
var authorisationHeader = sb.ToString().TrimEnd(' ').TrimEnd(',');
// Request Company Information
var request = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(ciUrl);
request.Headers.Add("Authorization", authorisationHeader);
request.Method = "GET";
request.ContentType = "application/json";
using (var response = (System.Net.HttpWebResponse)request.GetResponse())
{
// get 401
}
Used sandbox URL and added minorversion to the base URL
I attempted setting BASE_URL set to the sandbox url(https://sandbox-quickbooks.api.intuit.com/v3) and also set minorversion to be 4.
Any help is much appreciated.
Hopefully this helps, but here is a Java snippet using their SDK that works for me:
OAuthAuthorizer oauth = new OAuthAuthorizer(System.env.QB_OAUTH_CONSUMER_KEY, System.env.QB_OAUTH_CONSUMER_SECRET,
vendor.intuitOAuthAccessToken, vendor.intuitOAuthAccessSecret);
UUID trackingID = UUID.randomUUID()
log.info("About to init Context companyID=" + vendor.realmId + ", app_token=" + System.env.QB_APP_TOKEN + ", uuid=" + trackingID.toString())
Context context = new Context(oauth, System.env.QB_APP_TOKEN, ServiceType.QBO, vendor.realmId)
context.setMinorVersion("4")
context.setTrackingID(trackingID)
log.info("About to set BaseURL")
Config.setProperty(Config.BASE_URL_QBO, System.env.QB_BASE_URL + "/v3/company");
log.info("About to init DataService")
// get all customers
log.info("About to executeQuery")
DataService service = new DataService(context)
QueryResult queryResult = service.executeQuery("select * from customer");
In my case, QB_BASE_URL=https://sandbox-quickbooks.api.intuit.com
*NOTE there isn't a trailing slash
vendor.intuitOAuthAccessToken and vendor.intuitOAuthAccessSecret are the values you get back after the oauth flow
I'm attempting to update an existing, working Xamarin app to use ModernHttpClient. The app uses Azure REST calls to create containers and upload blobs to Azure Storage.
When I add new NativeMessageHandler() to each new HttpClient() statement to enable ModernHttpClient, the Azure Container continues to get created without any problem, but the call to upload the Blob returns Forbidden.
Here's the code to upload blobs (derived from other's work):
private async Task<bool> PutBlob(String containerName, String blobName, string photoPath)
{
byte[] blobContent = System.IO.File.ReadAllBytes(photoPath);
const String blobType = "BlockBlob";
String requestMethod = "PUT";
Int32 blobLength = blobContent.Length;
String urlPath = String.Format("{0}/{1}", containerName, blobName);
String msVersion = "2009-09-19";
String dateInRfc1123Format = DateTime.UtcNow.ToString("R", CultureInfo.InvariantCulture);
String canonicalizedHeaders = String.Format("x-ms-blob-type:{0}\nx-ms-date:{1}\nx-ms-version:{2}", blobType, dateInRfc1123Format, msVersion);
String canonicalizedResource = String.Format("/{0}/{1}", AzureStorageConstants.Account, urlPath);
String stringToSign = String.Format("{0}\n\n\n{1}\n\n\n\n\n\n\n\n\n{2}\n{3}", requestMethod, blobLength, canonicalizedHeaders, canonicalizedResource);
String authorizationHeader = SignThis(stringToSign);
string uri = AzureStorageConstants.BlobEndPoint + urlPath;
HttpClient client = new HttpClient(new NativeMessageHandler());
client.DefaultRequestHeaders.Add("x-ms-blob-type", blobType);
client.DefaultRequestHeaders.Add("x-ms-date", dateInRfc1123Format);
client.DefaultRequestHeaders.Add("x-ms-version", msVersion);
client.DefaultRequestHeaders.Add("Authorization", authorizationHeader);
bool isSuccess = false;
var UploadBlobTimer = Insights.TrackTime("UploadBlobTime");
UploadBlobTimer.Start();
using (HttpContent requestContent = new ByteArrayContent(blobContent))
{
HttpResponseMessage response = await client.PutAsync(uri, requestContent);
isSuccess = response.IsSuccessStatusCode;
}
UploadBlobTimer.Stop();
return isSuccess;
}
UPDATE
Below are the Response Headers from a successful .Net and unsuccessful Modern PutBlob call:
.Net
Transfer-Encoding: chunked
ETag: 0x8D280EE1D2ACEFF
Server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-request-id: 0a35e186-0001-0056-4dd6-b22ebd000000
x-ms-version: 2009-09-19
Date: Tue, 30 Jun 2015 01:49:18 GMT
Modern
Date: Tue, 30 Jun 2015 01:51:22 GMT
OkHttp-Received-Millis: 1435629095708
OkHttp-Selected-Protocol: http/1.1
OkHttp-Sent-Millis: 1435629083933
Server: Microsoft-HTTPAPI/2.0
x-ms-request-id: c18abaec-0001-0033-09d7-b29fe0000000
Any help is appreciated!