Phabricator conduit.connect C# Certificate Error - c#

I am trying to write an interface to our Phabricator install to allow out internal improvement system to create tasks. However, I cannot figure out why I keep getting a certificate error.
"{\"result\":null,\"error_code\":\"ERR-INVALID-CERTIFICATE\",\"error_info\":\"Your authentication certificate for this server is invalid.\"}"
The following is my code;
private void CreateSession()
{
int token = (int)((DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds);
var result = this.Do(
"conduit.connect",
new
{
client = this.ClientName,
clientVersion = this.ClientVersion,
clientDescription = "HIS to Fabricator Connector",
user = this.User,
authToken = token,
authSignature = SHA1HashStringForUTF8String(token + this.Certificate)
});
this.m_SessionKey = result.sessionKey;
this.m_ConnectionID = result.connectionID;
}
public static string SHA1HashStringForUTF8String(string s)
{
byte[] bytes = Encoding.UTF8.GetBytes(s);
var sha1 = SHA1.Create();
byte[] hashBytes = sha1.ComputeHash(bytes);
return HexStringFromBytes(hashBytes);
}
public static string HexStringFromBytes(byte[] bytes)
{
var sb = new StringBuilder();
foreach (byte b in bytes)
{
var hex = b.ToString("x2");
sb.Append(hex);
}
return sb.ToString();
}
This returns the following JSON;
"{\"client\":\"HIS\",\"clientVersion\":\"1\",\"clientDescription\":\"HIS to Fabricator Connector\",\"user\":\"KYLIE\",\"authToken\":1449486922,\"authSignature\":\"ec020edbd5082d3971c2c11ef4f4917244fc4a78\"}"
I think the issue is the certificate I am passing. I am using;
api-3ydcae2gtmf6u6uer2zow465j6px
which I obtained from the Conduit API Tokens page.
Any pointers?

You have to get the token via .../conduit/token
Use that token to query .../api/conduit.getcertificate
As result you get the certificate -> profit! :)
PS: it's neither api- nor cli- token to query the certificate! ;)

Related

C# Client generated RSA-Signature NodeJS server side validation fails

Dear Community,
fast forward. After an initial request I receive an random string from a server.
The client(ME) needs to generate an Digital-Signature via C# and send it back to the Node.js API (Express;TypeScript).
Then the server validats the signature and returns true, if the signature is successfully verified or false if not.
To sign the string I use C# default RSA object and SHA256 for Hashing.
The Server knows my public key and user identifier to make sure the digital-signature belongs to me.
Use-Case Tl;Dr:
Client(C#):
Receive a string from the server. Generate an digital-signature(RSA;SHA256) of this string and send it back via API-Request towards the Server.
Server(NodeJS;Express;TypeScript):
Receive the request with the digital-signature of the string inside and validats it.
Send an answer with true if the signature is successfully verified or false if not.
**The Problem:**
The result turns nerver out as true.
Generating an Signature of the string and Verify it localy, both systems (client and server) will return true.
Means if the Client generate a signature of the string and verifys it the process results localy in true.
If the server uses the same Key-Pair as the client and generate a signature of the same string the process will result in true.
BUT using the same Key-Pair both systems generate different signatures for the same string!
If I use the digital-signature of the string generated by the server and send it with the client, the server returns TRUE.
Code is a bit different. Names has changed.
Client (C#)
Request Methode
<!-- language: c# -->
private async Task<string> APIRequestSignature(RSA my_rsa, string randomString)
{
byte[] randomBytes = Encoding.UTF8.GetBytes(randomString);
byte[] signature = Crypto.GetDigitalSignatur256(randomBytes, my_rsa);
MeRequest meRequest = new(identifier, Convert.ToBase64String(signature));
var request = new HttpRequestMessage
{
Method = HttpMethod.Get,
RequestUri = APIUri.ValidME,
Content = new StringContent(meRequest.ToString(), Encoding.UTF8, MediaTypeNames.Application.Json),
};
var response = await client.SendAsync(request).ConfigureAwait(false);
response.EnsureSuccessStatusCode();
string responseBody = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
Console.WriteLine(responseBody);
}
internal class MeRequest: Request
{
private string sign;
public MeRequest(string identifier, string sign) : base(identifier, "")
{
this.sign = sign;
}
public string signature
{
get
{
return this.sign;
}
}
}
Crypto Class:
<!-- language: c# -->
public static byte[] GetDigitalSignatur256(byte[] str, RSA rsa)
{
byte[] hash = Hash256(str);
RSAPKCS1SignatureFormatter rsaFormatter = new(rsa);
rsaFormatter.SetHashAlgorithm("SHA256");
return rsaFormatter.CreateSignature(hash);
}
public static byte[] Hash256(byte[] arr) =>SHA256.Create().ComputeHash(arr);
Messi JavaScript Server Code: (Node.JS;Express;TypeScript)
<!-- language: lang-js -->
import \{Encryption\} from "../class/Encryption";
var randomString = "TESTTESTTESTTEST";
<!-- language: lang-js -->
//If User Exists need Ident and PKey /Get an random encrypted string
UserRoutes.get('/UserExist', function(req, res) {
//Create Hash from randomString
var hash = crypto.createHash("SHA256");
hash.update(randomString, "base64");
var randomStringHash = hash.digest("base64");
//Read Private Key from Client for Test Signature
var clientPrivateKey = fs.readFileSync(config.server.clientKeyPath + "identlarspk.txt", 'utf8');
//Create Sign with Hash from RandomString
var sign = crypto.createSign("SHA256");
sign.update(randomStringHash, "base64");
sign.end();
var signature = sign.sign({
key: clientPrivateKey,
padding: crypto.constants.RSA_PKCS1_PADDING
});
console.log("Signature Created By Server: " + signature);
res.json({
randomString: randomString
})
});
<!-- language: lang-js -->
//Validate User by Ident and Manipulated random encrypted String By Signature
UserRoutes.get('/UserSigning', async function(req, res) {
var encryption = new Encryption();
//Formating Public key
var userPKeyDB = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqdKBCUssRLefK9EzzRKxm+ftQ26PLmI5utmmGY6LgwEnKuIrJw/cWA5Fn+2ebJNAgdH9uFBAh8CEtHHjnfMB0SWCl6Qv8R62x8wJs8xNmoTIVLENe5lvHGi2FLVmzLg1LInfwqfsLBLmCM6re5WtQPX4BiXjfDaeYxYCLg3plfaQyYe9/PCzpswC4U4R3yMKzW3ptj4D+L0BGwp4EKFkh2qGJ1Bnm2PkDwott7CT8a8ef36vS7x1fb0XUuw4b5c87ilQZ+mG85aWDK45R7Tl2ZMebZsAe/kpLIRDsG3nnxdzpBelePFCGWSdCCwvFjygOcLyKXQtqJyp3tHvENGTjQIDAQAB";
var formatedEncryptionKey = await encryption.FormatePKey(userPKeyDB);
//Create Hash from RandomString
var hash = crypto.createHash("SHA256");
hash.update(randomString, "base64");
var randomStringHash = hash.digest("base64");
var bufferRandomStringHash = Buffer.from(randomStringHash, "base64");
var bufferClientSignature = Buffer.from(req.body.signature, "base64");
var verify = crypto.createVerify("SHA256");
verify.update(randomStringHash);
verify.end();
var isValidated = verify.verify(formatedEncryptionKey, bufferClientSignature);
res.json({
token: isValidated
})
});
<!-- language: lang-js -->
//Create start and end points for the Public Key in Encryption Class
public async FormatePKey(pKey: string): Promise<string> {
var bufferStartKey = Buffer.from("-----BEGIN PUBLIC KEY-----\n", "utf8");
var bufferStartKeyUTF8 = bufferStartKey.toString("utf8");
var bufferPubKey = Buffer.from(pKey, "base64");
var pubKeyBase64 = bufferPubKey.toString("base64");
var bufferEndKey = Buffer.from("\n-----END PUBLIC KEY-----", "utf8");
var bufferEndKeyUTF8 = bufferEndKey.toString("utf8");
var formatedPublicKey = bufferStartKeyUTF8 + pubKeyBase64 + bufferEndKeyUTF8;
var bufferPubicKey = Buffer.from(formatedPublicKey, "utf8");
var bufferPublicKeyUTF8 = bufferPubicKey.toString("utf8");
return bufferPublicKeyUTF8;
}

Create a valid JWT Token for DocuSign API

Ι try to create a valid jwt token
From settings i create an RSA keypairs and i get the private key without the "-----BEGIN RSA PRIVATE KEY----------END RSA PRIVATE KEY-----
"
var rsaPrivateKey = #"MIIEogIBAAKCAQEAoGujdXbYVy68a4CSWz963SpYxVs20/..............HQ/jW8pFom6gJreCDkca5axYo/gXp3W3rQHFTkooTNbOk2MyFMZUqRD3aCG1wuUW3w8TgGX4slrLDV0pP4=";
var jwt = Sign(rsaPrivateKey);
I follow the instructions here https://developers.docusign.com/docs/admin-api/admin101/application-auth/ and after a lot of hours i create this method
public string Sign(string privateKey)
{
List<string> segments = new List<string>();
var header = new { alg = "RS256", typ = "JWT" };
//For production environments, use account.docusign.com
var payload = new
{
iss = "4f489d61-dc8b------a828-3992e670dcbc",
iat = (Int32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds,
aud = "account-d.docusign.com",
scope = "signature impersonation"
};
byte[] headerBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(header, Formatting.None));
byte[] payloadBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(payload, Formatting.None));
segments.Add(Base64UrlEncode(headerBytes));
segments.Add(Base64UrlEncode(payloadBytes));
string stringToSign = string.Join(".", segments.ToArray());
byte[] bytesToSign = Encoding.UTF8.GetBytes(stringToSign);
byte[] keyBytes = Convert.FromBase64String(privateKey);
var privKeyObj = Asn1Object.FromByteArray(keyBytes);
var privStruct = RsaPrivateKeyStructure.GetInstance((Asn1Sequence)privKeyObj);
ISigner sig = SignerUtilities.GetSigner("SHA256withRSA");
sig.Init(true, new RsaKeyParameters(true, privStruct.Modulus, privStruct.PrivateExponent));
sig.BlockUpdate(bytesToSign, 0, bytesToSign.Length);
byte[] signature = sig.GenerateSignature();
segments.Add(Base64UrlEncode(signature));
return string.Join(".", segments.ToArray());
}
private static string Base64UrlEncode(byte[] input)
{
var output = Convert.ToBase64String(input);
output = output.Split('=')[0]; // Remove any trailing '='s
output = output.Replace('+', '-'); // 62nd char of encoding
output = output.Replace('/', '_'); // 63rd char of encoding
return output;
}
When i check the JWT validation in this tool https://jwt.io/#debugger-io, i get invalid signature error.
How can i fix the token ?? I cant proceed with Step 2 Obtain the access token...
I'm sorry you having problems with JWT. I would recommend you use the DocuSign C# SDK instead of trying to write your own code.
Then you can find the example of how to use JWT here - https://github.com/docusign/code-examples-csharp.
The specific code relevant to JWT is here - https://github.com/docusign/code-examples-csharp/blob/38c2eb46948a3cbf55edcce758f88d775f80cae9/launcher-csharp/Common/RequestItemService.cs under the UpdateUserFromJWT() method.
Common problems with JWT:
Not obtaining consent.
Using public token instead of private.
Using malform token. Token must be exactly, including new-lines, as provided.
Not using correct UserId (GUID) in the request.
Not requesting "impersonation" scope in consent (#1 above).

How to generate JWT Bearer Flow OAuth access tokens from a .net core client?

I'm having trouble getting my .NET Core client to generate OAuth access tokens for a salesforce endpoint that requires OAuth of type 'JWT Bearer Flow'.
It seems there are limited .NET Framework examples that show a .NET client doing this, however none that show a .NET Core client doing it
e.g.
https://salesforce.stackexchange.com/questions/53662/oauth-jwt-token-bearer-flow-returns-invalid-client-credentials
So in my .NET Core 3.1 app i've generated a self signed certificate, added the private key to the above example's code when loading in the certificate, however a System.InvalidCastExceptionexception exception occurs on this line:
var rsa = certificate.GetRSAPrivateKey() as RSACryptoServiceProvider;
Exception:
System.InvalidCastException: 'Unable to cast object of type 'System.Security.Cryptography.RSACng' to type 'System.Security.Cryptography.RSACryptoServiceProvider'.'
It appears that this private key is used in the JWT Bearer Flow as part of the signature, and perhaps RSACryptoServiceProvider is not used in .NET core as it was in .NET Framework.
My question is this - is there actually a way in .NET Core to generate access tokens for the OAuth JWT Bearer Flow?
Full code that I'm using:
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
var token = GetAccessToken();
}
static dynamic GetAccessToken()
{
// get the certificate
var certificate = new X509Certificate2(#"C:\temp\cert.pfx");
// create a header
var header = new { alg = "RS256" };
// create a claimset
var expiryDate = GetExpiryDate();
var claimset = new
{
iss = "xxxxxx",
prn = "xxxxxx",
aud = "https://test.salesforce.com",
exp = expiryDate
};
// encoded header
var headerSerialized = JsonConvert.SerializeObject(header);
var headerBytes = Encoding.UTF8.GetBytes(headerSerialized);
var headerEncoded = ToBase64UrlString(headerBytes);
// encoded claimset
var claimsetSerialized = JsonConvert.SerializeObject(claimset);
var claimsetBytes = Encoding.UTF8.GetBytes(claimsetSerialized);
var claimsetEncoded = ToBase64UrlString(claimsetBytes);
// input
var input = headerEncoded + "." + claimsetEncoded;
var inputBytes = Encoding.UTF8.GetBytes(input);
// signature
var rsa = (RSACryptoServiceProvider) certificate.GetRSAPrivateKey();
var cspParam = new CspParameters
{
KeyContainerName = rsa.CspKeyContainerInfo.KeyContainerName,
KeyNumber = rsa.CspKeyContainerInfo.KeyNumber == KeyNumber.Exchange ? 1 : 2
};
var aescsp = new RSACryptoServiceProvider(cspParam) { PersistKeyInCsp = false };
var signatureBytes = aescsp.SignData(inputBytes, "SHA256");
var signatureEncoded = ToBase64UrlString(signatureBytes);
// jwt
var jwt = headerEncoded + "." + claimsetEncoded + "." + signatureEncoded;
var client = new WebClient();
client.Encoding = Encoding.UTF8;
var uri = "https://login.salesforce.com/services/oauth2/token";
var content = new NameValueCollection();
content["assertion"] = jwt;
content["grant_type"] = "urn:ietf:params:oauth:grant-type:jwt-bearer";
string response = Encoding.UTF8.GetString(client.UploadValues(uri, "POST", content));
var result = JsonConvert.DeserializeObject<dynamic>(response);
return result;
}
static int GetExpiryDate()
{
var utc0 = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
var currentUtcTime = DateTime.UtcNow;
var exp = (int)currentUtcTime.AddMinutes(4).Subtract(utc0).TotalSeconds;
return exp;
}
static string ToBase64UrlString(byte[] input)
{
return Convert.ToBase64String(input).TrimEnd('=').Replace('+', '-').Replace('/', '_');
}
Well - it turns out posting to stackoverflow gets the brain cogs turning.
The answer ended up being doing a deep dive to find a similar issue here and using the solution from x509certificate2 sign for jwt in .net core 2.1
I ended up replacing the following code:
var cspParam = new CspParameters
{
KeyContainerName = rsa.CspKeyContainerInfo.KeyContainerName,
KeyNumber = rsa.CspKeyContainerInfo.KeyNumber == KeyNumber.Exchange ? 1 : 2
};
var aescsp = new RSACryptoServiceProvider(cspParam) { PersistKeyInCsp = false };
var signatureBytes = aescsp.SignData(inputBytes, "SHA256");
var signatureEncoded = ToBase64UrlString(signatureBytes);
With this code which makes use of the System.IdentityModel.Tokens.Jwt nuget package:
var signingCredentials = new X509SigningCredentials(certificate, "RS256");
var signature = JwtTokenUtilities.CreateEncodedSignature(input, signingCredentials);
Full code after solution:
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
var token = GetAccessToken();
}
static dynamic GetAccessToken()
{
// get the certificate
var certificate = new X509Certificate2(#"C:\temp\cert.pfx");
// create a header
var header = new { alg = "RS256" };
// create a claimset
var expiryDate = GetExpiryDate();
var claimset = new
{
iss = "xxxxx",
prn = "xxxxx",
aud = "https://test.salesforce.com",
exp = expiryDate
};
// encoded header
var headerSerialized = JsonConvert.SerializeObject(header);
var headerBytes = Encoding.UTF8.GetBytes(headerSerialized);
var headerEncoded = ToBase64UrlString(headerBytes);
// encoded claimset
var claimsetSerialized = JsonConvert.SerializeObject(claimset);
var claimsetBytes = Encoding.UTF8.GetBytes(claimsetSerialized);
var claimsetEncoded = ToBase64UrlString(claimsetBytes);
// input
var input = headerEncoded + "." + claimsetEncoded;
var inputBytes = Encoding.UTF8.GetBytes(input);
var signingCredentials = new X509SigningCredentials(certificate, "RS256");
var signature = JwtTokenUtilities.CreateEncodedSignature(input, signingCredentials);
// jwt
var jwt = headerEncoded + "." + claimsetEncoded + "." + signature;
var client = new WebClient();
client.Encoding = Encoding.UTF8;
var uri = "https://test.salesforce.com/services/oauth2/token";
var content = new NameValueCollection();
content["assertion"] = jwt;
content["grant_type"] = "urn:ietf:params:oauth:grant-type:jwt-bearer";
string response = Encoding.UTF8.GetString(client.UploadValues(uri, "POST", content));
var result = JsonConvert.DeserializeObject<dynamic>(response);
return result;
}
static int GetExpiryDate()
{
var utc0 = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
var currentUtcTime = DateTime.UtcNow;
var exp = (int)currentUtcTime.AddMinutes(4).Subtract(utc0).TotalSeconds;
return exp;
}
static string ToBase64UrlString(byte[] input)
{
return Convert.ToBase64String(input).TrimEnd('=').Replace('+', '-').Replace('/', '_');
}
I am replying to this question just because such a similar answer would have helped me a lot when I landed on this page the first time.
First of all you don't have to generate the JWT from the C# client.
To generate a JWT token you can use this website: https://jwt.io/
There is a very well done video showing how to generate a JWT token:
https://www.youtube.com/watch?v=cViU2-xVscA&t=1680s
Once generated, use it from your C# client to call the get access_token endpoint
https://developer.salesforce.com/docs/atlas.en-us.api_iot.meta/api_iot/qs_auth_access_token.htm
(Watch the video on YT)
If all is correct you will get the access_token
To run the API calls, all you need is the access_token and not the JWT.
Once you have it add it to the HTTP calls like this
public static void AddBearerToken(this HttpRequestMessage request, string accessToken)
{
request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken);
}
From time to time the access_token will expire. To check its validity you can call the token introspect api
https://help.salesforce.com/s/articleView?id=sf.remoteaccess_oidc_token_introspection_endpoint.htm&type=5
You need to pass two additional parameters: client_id and client_secret
The client_id is the Consumer Key. You get it from the Connected App in Salesforce
The client_server is the Consumer Secret. You get it from Connected App in Salesforce
If the introspect token API returns a response with
{ active: false, ... }
it means that the access_token is expired and you need to issue a new one.
To issue a new access_token simply call the "/services/oauth2/token" again using the same JWT.

How to send SSO claims to a Sitefinity based site from a non-Sitefinity application?

Please help.
How can I send claims to a Sitefinity based site from a non-Sitefinity application.
I have Sitefinity site user login/password and Membership provider name.
As a result I need Sitefinity site opened in the browser with my user already logged in.
I create a token with the following method :
private string CreateToken(string name)
{
var key = this.HexToByte("... here is the same hexadecimal code that is specified in SecurityConfug.config file in securityTokenIssuers tag ... ");
var sb = new StringBuilder();
// here I'm adding info from claims, only these two claims are needed
sb.AppendFormat("{0}={1}&", UrlEncode(ClaimTypes.Name), name);
sb.AppendFormat("{0}={1}&", UrlEncode("http://schemas.sitefinity.com/ws/2011/06/identity/claims/domain"), "Default");
sb
.AppendFormat("TokenId={0}&", UrlEncode(Guid.NewGuid().ToString()))
.AppendFormat("Issuer={0}&", UrlEncode("http://localhost"))
.AppendFormat("Audience={0}&", UrlEncode("http://localhost"))
.AppendFormat("ExpiresOn={0:0}", (DateTime.UtcNow.AddDays(1) - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds );
var unsignedToken = sb.ToString();
var hmac = new HMACSHA256(key);
var sig = hmac.ComputeHash(Encoding.ASCII.GetBytes(unsignedToken));
string signedToken = String.Format("{0}&HMACSHA256={1}",
unsignedToken,
UrlEncode(Convert.ToBase64String(sig)));
return signedToken;
}
private byte[] HexToByte(string hexString)
{
byte[] returnBytes = new byte[hexString.Length / 2];
for (int i = 0; i < returnBytes.Length; i++)
returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
return returnBytes;
}
And then I'm sending my token either via GET or via POST method as a parameter named wrap_access_token. If I use GET method, I encode the token using the method below. If I use POST method, then I do not need to encode it additionally.
var token = CreateToken(login);
var wrapped_token = UrlEncode(token);
Response.Redirect(baseUrl + "/?wrap_access_token=" + wrapped_token);
private string UrlEncode(string input)
{
var encodedInput = WebUtility.UrlEncode(input);
encodedInput = Regex.Replace(encodedInput, "(%[0-9A-F]{2})", c => c.Value.ToLowerInvariant());
return encodedInput;
}

oauth_problem=token_rejected when refreshing Yahoo's OAuth Access Token

I've done Oauth with Hammock, I succeed to get access token, access token secret and session handle but now I must get the refresh access token when the token expired.
I've followed the instruction and I tried to pass the access token with urldecode and without urldecode but I can't get the token, I obtain
oauth_problem=token_rejected
UPDATE:
that's my code:
##the call##
var AccessTokenQuery = OAuthUtil.GetAccessTokenQueryRenewal(accessToken, session_handle, accessTokenSecret);
AccessTokenQuery.RequestAsync(AppSettings.AccessTokenUri, null);
AccessTokenQuery.QueryResponse += new EventHandler<WebQueryResponseEventArgs>(AccessTokenQuery_QueryResponse);
internal static OAuthWebQuery GetAccessTokenQueryRenewal(string oauth_token,string session_handle, string oauth_token_secret)
{
var oauth = new OAuthWorkflow
{
AccessTokenUrl = AppSettings.AccessTokenUri,
ConsumerKey = AppSettings.consumerKey,
ConsumerSecret = AppSettings.consumerKeySecret,
SignatureMethod = OAuthSignatureMethod.HmacSha1,
ParameterHandling = OAuthParameterHandling.HttpAuthorizationHeader,
TokenSecret = oauth_token_secret,
Token = oauth_token,
SessionHandle = session_handle,
Version = AppSettings.oAuthVersion
};
var info = oauth.BuildAccessTokenInfo(WebMethod.Post);
var objOAuthWebQuery = new OAuthWebQuery(info, false);
objOAuthWebQuery.HasElevatedPermissions = true;
objOAuthWebQuery.SilverlightUserAgentHeader = "Hammock";
return objOAuthWebQuery;
}
void AccessTokenQuery_QueryResponse(object sender, WebQueryResponseEventArgs e)
{
try
{
StreamReader reader = new StreamReader(e.Response);
string strResponse = reader.ReadToEnd();
var parameters = MainUtil.GetQueryParameters(strResponse);
accessToken = parameters["oauth_token"];
accessTokenSecret = parameters["oauth_token_secret"];
session_handle = parameters["oauth_session_handle"];
MainUtil.SetKeyValue<string>("AccessToken", accessToken);
MainUtil.SetKeyValue<string>("AccessTokenSecret", accessTokenSecret);
MainUtil.SetKeyValue<string>("SessionHandle", session_handle);
userLoggedIn();
}
catch (Exception ex)
{
Dispatcher.BeginInvoke(() =>
{
MessageBox.Show(ex.Message);
});
}
}
Quick possibility you could try: you said you 'tried to pass the access token with urldecode'. Have you tried using urlencode? Urldecode is used for decoding urls returned from a web call, encoding is what is done before passing to a web call.
Also, note that the encoding scheme for Oauth is slightly different than the one used in .NET 's default encoding. You can easily write your own encoding routine though, check out the oauth spec for details.
Ex:
private string UrlEncode(string value)
{
string unreserved = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~";
StringBuilder result = new StringBuilder();
foreach (char symbol in value)
{
if (unreserved.IndexOf(symbol) != -1)
result.Append(symbol);
else
result.Append('%' + String.Format("{0:X2}", (int)symbol));
}
return result.ToString();
}

Categories

Resources