I' getting following error when I try to run the application in the server. Some of APIs working in the server without an issue and only one API giving following error.
javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
at sun.security.ssl.SSLSessionImpl.getPeerCertificates(SSLSessionImpl.java:397)
at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:128)
at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:390)
at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:148)
at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:149)
This is the code I'm trying to access the API.
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(
"https://mife.smobile.lk/apicall/dialogloanprepaid/v1.0/auto");
JSONObject json = new JSONObject();
StringEntity params = new StringEntity("{\"msisdn\":\"" + mobile
+ "\",\"channel\":\"IVR\"}");
new StringEntity(json.toString());
post.addHeader("content-type", "application/json");
post.addHeader("Authorization", "Bearer " + access_token);
post.addHeader("Accept", "application/json");
post.setEntity(params);
HttpResponse response = client.execute(post);
int status = response.getStatusLine().getStatusCode();
System.out.println("status code is :" + status);
resCode = Integer.toString(status);
BufferedReader rd = new BufferedReader(new InputStreamReader(
response.getEntity().getContent()));
String response1 = readAll(rd);
System.out.println(response1);
JSONObject obj = new JSONObject(response1);
resCode = obj.getString("resCode");
resDesc = obj.getString("resDesc");
Is there anything can be done from the code level in order to sort out the issue. Please help.
I have wired up the JwtAuthForWebAPI nuget project but I am not able to validate the generated tokens. I end up getting a 500 error. I am using the exact same key value for both token generation and also when configuring JwtAuthenticationMessageHandler.
This is the code to generate a token:
var tokenHandler = new JwtSecurityTokenHandler();
var symmetricKey = JsonWebTokenSecretKey.GetBytes();
var now = DateTime.UtcNow;
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(
new[]{
new Claim(JwtClaimKeys.Audience, SessionManager.Current.ApplicationId.ToString()),
new Claim(JwtClaimKeys.Subject, userLoginRequest.ApplicationInstanceId.ToString())
}),
TokenIssuerName = "My Company",
Lifetime = new Lifetime(now, now.AddMinutes(tokenLifetimeInMinutes)),
SigningCredentials = new SigningCredentials(
new InMemorySymmetricSecurityKey(symmetricKey),
"http://www.w3.org/2001/04/xmldsig-more#hmac-sha256",
"http://www.w3.org/2001/04/xmlenc#sha256")
};
tokenDescriptor.Subject.AddClaims(GetRoles(userLoginRequest));
var token = tokenHandler.CreateToken(tokenDescriptor);
return tokenHandler.WriteToken(token);
This is the code to register the authentication handler:
var keyBuilder = new SecurityTokenBuilder();
var jwtHandler = new JwtAuthenticationMessageHandler
{
Issuer = "My Company",
AllowedAudience = ApplicationId.ToString(),
SigningToken = keyBuilder.CreateFromKey(JsonWebTokenSecretKey),
PrincipalTransformer = new MyUserPrincipleTransformer()
};
config.MessageHandlers.Add(jwtHandler);
This is the error I get:
{"Message":"An error has occurred.","ExceptionMessage":"IDX10503: Signature validation failed. Keys tried: 'System.IdentityModel.Tokens.InMemorySymmetricSecurityKey\r\n'.\nExceptions caught:\n ''.\ntoken: '{\"typ\":\"JWT\",\"alg\":\"HS256\"}.{\"aud\":\"1\",\"sub\":\"3\",\"role\":[\"User\",\"Admin\"],\"iss\":\"My Company\",\"exp\":1429547369,\"nbf\":1429543769}'","ExceptionType":"System.IdentityModel.SignatureVerificationFailedException",
"StackTrace":"
at System.IdentityModel.Tokens.JwtSecurityTokenHandler.ValidateSignature(String token, TokenValidationParameters validationParameters)\r\n
at System.IdentityModel.Tokens.JwtSecurityTokenHandler.ValidateToken(String securityToken, TokenValidationParameters validationParameters, SecurityToken& validatedToken)\r\n
at JwtAuthForWebAPI.JwtSecurityTokenHandlerAdapter.ValidateToken(IJwtSecurityToken securityToken, TokenValidationParameters validationParameters)\r\n
at JwtAuthForWebAPI.JwtAuthenticationMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)\r\n
at System.Web.Http.HttpServer.<SendAsync>d__0.MoveNext()"}
This is an example JSON token:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiIxIiwic3ViIjoiMyIsInJvbGUiOlsiVXNlciIsIkFkbWluIl0sImlzcyI6Ik15IENvbXBhbnkiLCJleHAiOjE0Mjk1NTE4MjgsIm5iZiI6MTQyOTU0ODIyOH0.9wA_RBir9u7Cn_-Fy2T-Q_IDUfz6B928IEbIgXD9Bug
Interestingly, I am able to validate the token with my key using http://jwt.io. I suspect it may have something to do with the JwtAuthForWebAPI library looking at something different than what the System.Identity JWT library is generating?
this is Jamie (author of the JwtAuthForWebAPI package). The server config code - specifically, SecurityTokenBuilder.CreateFromKey(string) - assumes the given string is base64 encoded. It was either that, or assumptions or parameters are needed that would indicate which encoding to use for converting to a byte array. I chose to assume the string was base64 encoded. I'm sure there's a clearer way to go about converting the string key into a SecurityToken, but that's the way the code is today.
In SmokeTests.cs within the JwtAuthForWebAPI.SampleClient project, you can see that I used the Convert.FromBase64String() method, as opposed to using the GetBytes() method from an Encoding class:
public const string SymmetricKey = "YQBiAGMAZABlAGYAZwBoAGkAagBrAGwAbQBuAG8AcABxAHIAcwB0AHUAdgB3AHgAeQB6ADAAMQAyADMANAA1AA==";
// ...
var key = Convert.FromBase64String(SymmetricKey);
var credentials = new SigningCredentials(
new InMemorySymmetricSecurityKey(key),
"http://www.w3.org/2001/04/xmldsig-more#hmac-sha256",
"http://www.w3.org/2001/04/xmlenc#sha256");
Feel free to keep using your current token generation code, but on the server...
Please try specifying a base64 encoded version of JsonWebTokenSecretKey in the server configuration code. You can use a site like https://www.base64encode.org/ to encode it, or try code like this:
var base64key = Convert.ToBase64String(Encoding.UTF8.GetBytes(JsonWebTokenSecretKey));
var keyBuilder = new SecurityTokenBuilder();
var jwtHandler = new JwtAuthenticationMessageHandler
{
Issuer = "My Company",
AllowedAudience = ApplicationId.ToString(),
SigningToken = keyBuilder.CreateFromKey(base64key),
PrincipalTransformer = new MyUserPrincipleTransformer()
};
Let me know whether or not that works.
Also, I'm going to update the library to catch the SignatureVerificationFailedException exception and return a 401, as opposed to letting an internal server error happen. You'll still need to specify your key as a base64 string, but at least such configuration issues won't cause a 500 error.
Again, please let me know if that does the trick.
it's just my code sample base on #Jamie answer
protected string GetUsername(string token)
{
string secret = "keyyyyy!#3";
var key = Convert.FromBase64String(secret);
var IssuerSigningKey = new SymmetricSecurityKey(key);
IdentityModelEventSource.ShowPII = true;
var SigningCredentials = new SigningCredentials(
IssuerSigningKey,
SecurityAlgorithms.HmacSha256Signature);
var handler = new JwtSecurityTokenHandler();
var tokenSecure = handler.ReadToken(token) as SecurityToken;
var validations = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = IssuerSigningKey,
ValidateIssuer = false,
ValidateAudience = false
};
var claims = handler.ValidateToken(token, validations, out tokenSecure);
return claims.Identity.Name;
}
I am using .NET to list the payments from my square account.
I am able to get a list of the payments, but to get the description field I have to go one level deeper and make http end point calls for each payment. This is time consuming.
Question: Can anyone provide me with a sample in Visual C# or Java to make batch calls for retrieving payments (using multiple payment id's)?
Your help is greatly appreciated.
Thanks,
Prashant
#Andrew - Here's what I am using, I am just not sure how to add the headers for batch payments retrieval.
string res = string.Empty;
string qs = string.Empty;
foreach (string s in parameters.Keys)
{
if (qs == string.Empty)
qs = "?";
else
qs += "&";
qs += s + "=" + parameters[s];
}
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(_connectUrl + "/" + command + qs); ///
request.Proxy = null;
request.Headers.Add("Authorization", "Bearer " + _accessToken);// ");
request.ContentType = "application/json";
request.Method = method; // "GET";
try { HttpWebResponse responseGet = (HttpWebResponse)request.GetResponse();
StreamReader reader = new StreamReader(responseGet.GetResponseStream());
StringBuilder output = new StringBuilder();
output.Append(reader.ReadToEnd());
responseGet.Close();
request = null;
return output.ToString();
}
catch (Exception exp)
Looks like I've been able to answer my own query.
We need to be able to send the following POST to the HTTP Endpoint
{"requests":[{"method":"GET","relative_path":"/v1/me/payments/<payment_id>","access_token":"XXXX","request_id":"1"},{"method":"GET","relative_path":"/v1/me/payments/<payment_id>","access_token":"XXXX","request_id":"2"}]}
the following code in .NET achieves the above
//Convert the body of request into a byte array
byte[] byteArray = Encoding.UTF8.GetBytes(body);
//Set the length
request.ContentLength = byteArray.Length;
//Write the body to the request by using a datastream
//This line never returns....
Stream datastream = request.GetRequestStream();
datastream.Write(byteArray, 0, byteArray.Length);
datastream.Close();
And that's all there is to it.
Hope this helps anyone is is set out to use the batch mode.
Thanks
I'm trying to integrate with an API that requires a PUT to update data:
Here's an example from them using curl:
curl --request PUT \
--user-agent "Your Client Name/1.0" \
--header "Content-Type: application/xml" \
--data-binary '<order><status_id>10</status_id></order>' \
https://www.example.com/api/v2/orders/101
However, I'd need to use JSON (they support that as well) using .NET MVC 3. Any idea on how I can do that?
I use the code below for GET successfully:
Order obj = Call<Order>(url, "GET");
private T Call<T>(string url, string methodType) where T : class {
T result;
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
request.Method = methodType;
request.Accept = "application/json";
request.ContentType = "application/json";
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
using (StreamReader reader = new StreamReader(response.GetResponseStream())) {
JavaScriptSerializer jsSerializer = new JavaScriptSerializer();
string jsonData = reader.ReadToEnd();
result = (T)jsSerializer.Deserialize<T>(jsonData);
}
return result;
}
However, can I issue a PUT using a similar method?
Order obj = Call<Order>(url, "PUT");
If so, where do I put the data that's required in "data-binary"?
Well, here's a possible point of origin - untested; written straight into the browser; not production code; assumes that the PUT call both sends and receives the same object type (which is probably not the case)...
The main addition is that you need to supply the request's ContentLength, and you need to write the serialized JSON object to the request stream, which you'll get by calling HttpWebRequest::GetRequestStream(). It's the same approach as when POSTing.
private T Call<T>(string url, string methodType, T data) where T: class
{
T result;
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
request.Method = methodType;
request.ContentType = "application/json";
request.Accept = "application/json";
if (methodType == "PUT" || methodType == "POST")
{
JavaScriptSerializer jsSerializer = new JavaScriptSerializer();
string jsonData = jsSerializer.Serialize(data);
byte[] arrData = Encoding.UTF8.GetBytes(jsonData);
request.ContentLength = arrData.Length;
using (Stream dataStream = request.GetRequestStream())
{
dataStream.Write(arrData, 0, arrData.Length);
}
}
// Note: You may not need to parse any response content,
// or it may be a different class
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
using (StreamReader reader
= new StreamReader(response.GetResponseStream()))
{
JavaScriptSerializer jsSerializer = new JavaScriptSerializer();
string jsonData = reader.ReadToEnd();
result = (T)jsSerializer.Deserialize<T>(jsonData);
}
}
return result;
}
I am creating a program that auto login into a website using forms authentication. When ever I call my method to connect to the website, it returns me a empty document text. However, if I call the same method a second time, it works perfectly.
Here is my code :
//perform authentication and stores the session in the cookiecontainer
private void loginToSite()
{
// prepare the web page we will be asking for
request = (HttpWebRequest)
WebRequest.Create(#"http://diary.com/notes/my_journal");
request.KeepAlive = true;
//========================================
//start of forms authentication parameters
//========================================
string authInfo = username + ":" + password;
authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo));
request.Headers["Authorization"] = "Basic " + authInfo;
//========================================
//end of forms authentication parameters
//========================================
request.ContentType = "text/html";
request.Method = "GET";
request.AllowAutoRedirect = true;
request.Referer = #"http://diary.com/";
request.CookieContainer = new CookieContainer();
// execute the request
HttpWebResponse response = (HttpWebResponse)
request.GetResponse();
// we will read data via the response stream
Stream resStream = response.GetResponseStream();
container = request.CookieContainer;
//assign the http content to myWB for manipulation
//myWB is a WebBrowser object that have been declared
myWB.DocumentStream = resStream;
//prevent script errors from popping up
myWB.ScriptErrorsSuppressed = true;
MessageBox.Show(myWB.DocumentText);
}