having Issues connecting to quickbooks online via IPP and .net devkit - intuit-partner-platform

I am trying to connect to QB online and I am having issues. I have created a demo account for QBO and added my test app to the account and granted access for my app. I have my consumer key and secret tokens. I have installed the .net devkit and have my test project setup.
I am using the code example from here...
https://ipp.developer.intuit.com/0010_Intuit_Partner_Platform/0200_DevKits_for_Intuit_Partner_Platform/0100_IPP_.NET_DevKit/0299_Synchronous_Calls/0001_Data_Service_APIs
everything works until I call the add method to create a customer. the same goes for anything else I try to do as far as adding data.
This is the error I get...
"message=Exception authenticating OAuth; errorCode=003200; statusCode=401; source=OAuthStrategy; oauth_problem=token_rejected; cause=net.oauth.OAuthProblemException: token_rejected"
It says token rejected so I am unclear as to what I am missing. These are the tokens given to me in the online app section.
here is my code..
Dim AccessToken As String = [redacted]
Dim AccessTokenSecret As String = [redacted]
Dim ConsumerKey As String = [redacted]
Dim ConsumerSecret As String = [redacted]
Dim OAuthValidator As OAuthRequestValidator = New OAuthRequestValidator(AccessToken, AccessTokenSecret, ConsumerKey, ConsumerSecret)
Dim Context As ServiceContext = New ServiceContext(OAuthValidator, RealmID, IntuitServicesType.QBD)
Dim dataServices As DataServices = New DataServices(Context)
Dim qbdCustomer As Customer = New Customer()
With qbdCustomer
qbdCustomer.Name = "My New Customer"
qbdCustomer.GivenName = "New Customer"
qbdCustomer.FamilyName = "New Customer"
End With
Dim customerAdded As Customer = dataServices.Add(qbdCustomer)

If you are trying to connect to QBO, you are using the wrong entities.
You should be using QBO and NOT QBD.
Also, your InitializeServiceContext looks like it is missing some parameters.

Related

How to call SSRS Rest-Api V1.0 with custom security implemented (NOT SOAP)

I have implemented the custom security on my reporting services 2016 and it displays the login page once the URL for reporting services is typed on browser URL bar (either reports or reportserver)
I am using the following code to pass the Credentials
when i use the code WITHOUT my security extension it works and looks like this
ICredentials _executionCredentials;
CredentialCache myCache = new CredentialCache();
Uri reportServerUri = new Uri(ReportServerUrl);
myCache.Add(new Uri(reportServerUri.GetLeftPart(UriPartial.Authority)),
"NTLM", new NetworkCredential(MyUserName, MyUserPassword));
_executionCredentials = myCache;
when i use the code WITH the security extension it doesnt work and looks like this
ICredentials _executionCredentials;
CredentialCache myCache = new CredentialCache();
Uri reportServerUri = new Uri(ReportServerUrl);
myCache.Add(new Uri(reportServerUri.GetLeftPart(UriPartial.Authority)),
"Basic", new NetworkCredential(MyUserName, MyUserPassword));
_executionCredentials = myCache;
and i get an Exception saying "The response to this POST request did not contain a 'location' header. That is not supported by this client." when i actually use this credentials
Is "basic" the wrong option ?
Have anyone done this ?
Update 1
Well it turns out that my SSRS is expecting an Authorisation cookie
which i am unable to pass (according to fiddler, there is no cookie)
HttpWebRequest request;
request = (HttpWebRequest)HttpWebRequest.Create("http://mylocalcomputerwithRS/Reports_SQL2016/api/v1.0");
CookieContainer cookieJar = new CookieContainer();
request.CookieContainer = cookieJar;
Cookie authCookie = new Cookie("sqlAuthCookie", "username:password");
authCookie.Domain = ".mydomain.mylocalcomputerwithRS";
if (authCookie != null)
request.CookieContainer.Add(authCookie);
request.Timeout = -1;
HttpWebResponse myHttpWebResponse = (HttpWebResponse)request.GetResponse();
That's how I got it (SSRS 2017; api v2.0). I took the value for the "body" from Fiddler:
var handler = new HttpClientHandler();
var httpClient = new HttpClient(handler);
Assert.AreEqual(0, handler.CookieContainer.Count);
// Create a login form
var body = new Dictionary<string, string>()
{
{"__VIEWSTATE", "9cZYKBmLKR3EbLhJvaf1JI7LZ4cc0244Hpcpzt/2MsDy+ccwNaw9hswvzwepb4InPxvrgR0FJ/TpZWbLZGNEIuD/dmmqy0qXNm5/6VMn9eV+SBbdAhSupsEhmbuTTrg7sjtRig==" },
{"__VIEWSTATEGENERATOR", "480DEEB3"},
{ "__EVENTVALIDATION", "IS0IRlkvSTMCa7SfuB/lrh9f5TpFSB2wpqBZGzpoT/aKGsI5zSjooNO9QvxIh+QIvcbPFDOqTD7R0VDOH8CWkX4T4Fs29e6IL92qPik3euu5QpidxJB14t/WSqBywIMEWXy6lfVTsTWAkkMJRX8DX7OwIhSWZAEbWZUyJRSpXZK5k74jl4x85OZJ19hyfE9qwatskQ=="},
{"txtUserName", "User"},
{"txtPassword", "1"},
{"btnLogin","Войти"}
};
var content = new FormUrlEncodedContent(body);
// POST to login form
var response = await httpClient.PostAsync("http://127.0.0.1:777/ReportServer/Logon.aspx", content);
// Check the cookies created by server
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
var cookies = handler.CookieContainer.GetCookies(new Uri("http://127.0.0.1:777/ReportServer"));
Assert.AreEqual("sqlAuthCookie", cookies[0].Name);
// Make new request to secured resource
var myresponse = await httpClient.GetAsync("http://127.0.0.1:777/Reports/api/v2.0/Folders");
var stringContent = await myresponse.Content.ReadAsStringAsync();
Console.Write(stringContent);
As an alternative you can customize SSRS Custom Security Sample quite a bit.
I forked Microsoft's Custom Security Sample to do just what you are describing (needed the functionality at a client long ago and reimplemented as a shareable project on GitHub).
https://github.com/sonrai-LLC/ExtRSAuth
I created a YouTube walkthrough as well to show how one can extend and debug SSRS security with this ExtRSAuth SSRS security assembly https://www.youtube.com/watch?v=tnsWChwW7lA
TL; DR; just bypass the Microsoft example auth check in Login.aspx.cs and put your auth in Page_Load() or Page_Init() event of Login.aspx.cs- wherever you want to perform some custom logging check- and then immediately redirect auth'd user to their requested URI.

Should I use the GRAPH API or a simple SMTP class to create an email ?

I don't seem to get it. I can create some code to send an email like this:
String userName = "user#domain.com";
String password = "your password";
MailMessage msg = new MailMessage();
msg.To.Add(new MailAddress("ToAddress"));
msg.From = new MailAddress(userName);
msg.Subject = "Test Office 365 Account";
msg.Body = "Testing email using Office 365 account.";
msg.IsBodyHtml = true;
SmtpClient client = new SmtpClient();
client.Host = "smtp.office365.com";
client.Credentials = new System.Net.NetworkCredential(userName, password);
client.Port = 587;
client.EnableSsl = true;
client.Send(msg);
Or I can create an app in our Azure AD and set the permissions and send an email with the GRAPH API right?
Is there any possible reason I would want to use the GRAPH API to do this ?
Well you're asking for an opinion, so it's hard to give an all-inclusive answer. However, one reason that you might prefer Graph over SMTP is that it uses OAuth, so you do not need to ask for or store the user's username or password.

Google API v3 .Net client Unauthorized client or scope in request

I'm getting the error message "Unauthorized client or scope in request." When the following code executes. If I remove the .User = myUserEmail parameter I get a "Insufficient Permission [403]" error message. If I had to guess, I would guess that the issue is the .user parameter I'm using. But, I don't what I'm doing wrong there. I'm using the email address associated with the Google Account I normally use to login to Google Analytics.
Private myClientEmail As String = System.Configuration.ConfigurationManager.AppSettings("clientEmail").ToString()
Private myP12Path As String = System.Configuration.ConfigurationManager.AppSettings("p12Path").ToString()
Private myP12Password As String = System.Configuration.ConfigurationManager.AppSettings("p12Password").ToString()
Private myUserEmail As String = System.Configuration.ConfigurationManager.AppSettings("userEmail").ToString()
Private myApplicationName As String = System.Configuration.ConfigurationManager.AppSettings("applicationName").ToString()
Dim scopes As IList(Of String) = New List(Of String)()
scopes.Add("https://www.googleapis.com/auth/drive.readonly")
Dim certificate As X509Certificate2 = New X509Certificate2(myP12Path, myP12Password, X509KeyStorageFlags.Exportable)
Dim credential As ServiceAccountCredential = New ServiceAccountCredential(New ServiceAccountCredential.Initializer(myClientEmail) With {
.Scopes = scopes,
.User = myUserEmail
}.FromCertificate(certificate))
Dim service As AnalyticsService = New AnalyticsService(New BaseClientService.Initializer() With {
.HttpClientInitializer = credential,
.ApplicationName = myApplicationName
})
Dim profileId As String = "ga:12345678"
Dim startDate As String = DateTime.Today.AddDays(-1).ToString("yyyy-MM-dd")
Dim endDate As String = DateTime.Today.ToString("yyyy-MM-dd")
Dim metrics As String = "ga:visits"
Dim request As DataResource.GaResource.GetRequest = service.Data.Ga.Get(profileId, startDate, endDate, metrics)
request.Dimensions = "ga:date"
Dim data As GaData = request.Execute()
I found the error in my ways...
Somewhere along the lines I inadvertently changed the scope to the "drive.readonly". When I'm trying to work with the "analytics.readonly".

Reusing ClaimsPrincipal to authenticate against sharepoint online

I have an Office 365 account (using the latest SharePoint 2013 instance)
I also have a simple .net web app that is authenticating against Office 365, I created an AppPrincipalId and added it using New-MsolServicePrincipal powershell commmand.
This works correctly. I launch the app (in debug), it redirects to 365 login, I login, it comes back to the app, and I have derived a class from ClaimsAuthenticationManager and overriden the Authenticate method.
I can now see the ClaimsPrincipal, with the relevant claims and identity etc.
Now I would like to re-use this identity to programmatically access SharePoint.
My questions:
a) Will SharePoint permit this Identity (seeing that it was issued by sts.windows.net)
b) How can I reconstruct a valid JWT (or use the existing one), and encapsulate this in a HttpRequest using authentication bearer.
The code I am using is below - this is coming back 401 not authorized.
Any help would be highly appreciated.
public override ClaimsPrincipal Authenticate(string resourceName, ClaimsPrincipal incomingPrincipal)
{
if (incomingPrincipal != null && incomingPrincipal.Identity.IsAuthenticated == true)
{
List<Claim> claims = null;
claims = (from item in incomingPrincipal.Claims
where item.Type.StartsWith("http", StringComparison.InvariantCultureIgnoreCase)
select item).ToList();
RNGCryptoServiceProvider cryptoProvider = new RNGCryptoServiceProvider();
byte[] keyForHmacSha256 = Convert.FromBase64String("Gs8Qc/mAF5seXcGHCUY/kUNELTE=");
// Create our JWT from the session security token
JWTSecurityToken jwt = new JWTSecurityToken
(
"https://sts.windows.net/myAppIdGuid/",
"00000003-0000-0ff1-ce00-000000000000", // sharepoint id
claims,
new SigningCredentials(
new InMemorySymmetricSecurityKey(keyForHmacSha256),
"http://www.w3.org/2001/04/xmldsig-more#hmac-sha256",
"http://www.w3.org/2001/04/xmlenc#sha256"),
DateTime.UtcNow,
DateTime.UtcNow.AddHours(1)
);
var validationParameters = new TokenValidationParameters()
{
AllowedAudience = "00000003-0000-0ff1-ce00-000000000000", // sharepoint id
ValidIssuer = "https://sts.windows.net/myAppIdGuid/", // d3cbe is my app
ValidateExpiration = true,
ValidateNotBefore = true,
ValidateIssuer = true,
ValidateSignature = true,
SigningToken = new BinarySecretSecurityToken(Convert.FromBase64String("mySecretKeyFromPowerShellCommand")),
};
JWTSecurityTokenHandler jwtHandler = new JWTSecurityTokenHandler();
var jwtOnWire = jwtHandler.WriteToken(jwt);
var claimPrincipal = jwtHandler.ValidateToken(jwtOnWire, validationParameters);
JWTSecurityToken parsedJwt = jwtHandler.ReadToken(jwtOnWire) as JWTSecurityToken;
HttpWebRequest endpointRequest =
(HttpWebRequest)HttpWebRequest.Create(
"https://MySharepointOnlineUrl/_api/web/lists");
endpointRequest.Method = "GET";
endpointRequest.Accept = "application/json;odata=verbose";
endpointRequest.Headers.Add("Authorization",
"Bearer " + parsedJwt.RawData);
HttpWebResponse endpointResponse =
(HttpWebResponse)endpointRequest.GetResponse();
}
}
If your scenario is about consuming SharePoint Online data from a remote web app, you probably want to use the OAuth flow. You can't generate the token yourself. Instead you ask for consent to the user to access certain scopes (resource + permission). These two links should help
http://msdn.microsoft.com/en-us/library/office/apps/jj687470(v=office.15).aspx
http://jomit.blogspot.com.ar/2013/03/authentication-and-authorization-with.html

Apple In app purchase verify recurring payment in .NET Java 21002 exception

We are trying to verify a receipt for a RECURRING in-app payment made in iOS.
Referring to an earlier question on stack (http://stackoverflow.com/questions/11085847/keep-getting-21002-java-lang-nullpointerexception-on-apples-verifyreceipt), I manage to use the following code which sends in a JSON object made up of our receipt and sharedSecret key but we get the dreaded {"status":21002, "exception":"java.lang.NullPointerException"} error
Dim json As String ="{'receipt-data':'base64encoded receipt data','password':'YYYY'}"
Dim webRequest = System.Net.HttpWebRequest.Create("https://sandbox.itunes.apple.com/verifyReceipt")
webRequest.ContentType = "text/plain"
webRequest.Method = "POST"
Dim byteArray As Byte() = Encoding.UTF8.GetBytes(json)
webRequest.ContentLength = byteArray.Length
Using stream = webRequest.GetRequestStream()
stream.Write(byteArray, 0, byteArray.Length)
stream.Flush()
End Using
Dim resp = webRequest.GetResponse()
If resp IsNot Nothing Then
Using sr = New System.IO.StreamReader(resp.GetResponseStream())
Dim result = sr.ReadToEnd().Trim()
' always getting '21002' 'java.lang.NullPointerException'
Response.Write(result.ToString())
End Using
End If
Any help appreciated!