I am trying to write a program that simply connects up to a GP WebService and invokes it's GetCustomerList() method to get customers from Great Plains. The code I am outlining below is an duplication of what I was able to find in the documentation, however, when I run it I am getting a SoapException. I am not sure if I am missing credentials (eg. username and password) or if I am even invoking this properly. I believe that I have the Security settings set correctly in the Dynamics Security Console, but I am not 100% sure or if there is anything else I need to configure. Any help would be greatly appreciated.
public IList<string> GetCustomerNames()
{
//Added a ServiceReference to the actual WebService which appears to be working
var service = new DynamicsGPClient();
var context = new Context();
var customerKey = new CustomerKey();
var companyKey = new CompanyKey();
//Trying to load the test data
companyKey.Id = (-1);
context.OrganizationKey = (OrganizationKey)companyKey;
//Trying to load the test data
customerKey.Id = "AARONFIT0001";
var customers = service.GetCustomerList(new CustomerCriteria(), context);
return customers.Select(x => x.Name).ToList();
}
Sounds like a security issue ... are you getting a specific error message ... that might be helpful ...
Also found this ...
It sounds to me like you need a Windows App Pool Identity on your
webservice. Right now you have the IIS Security set to "anonymous", so the
clients aren't required to pass the credentials when they call your methods.
You'll need to turn that off and run your app pool as a windows account. Once
you've got that working, you can choose if you want to just add that one App
Pool identity into the security for webservices, and have all the operations
done as that account (poor security), or, in your wrapper, you could use the
HTTP User's context identity, and set it to the "WorkOnBehalfOf" property for
the GP WebService call you're actually using.
You'll have to give the App
Pool identity "WorkOnBehalfOf" permission in the web service security
console, and then whichever users you want to call the webservice. This keeps
the security model intact, and you're authorizing that the users calling the
wrapped webservice actually do have permission to call the original GP
Webservice methods. (This is how Business Portal forwards requests to the
webservices.)
https://groups.google.com/forum/?fromgroups=#!topic/microsoft.public.greatplains/W7gAo_zXit8
Related
I have a service account that I have created in a project in GCP. This service account will then be provided access to different domains using Domain-wide Delegation.
When the Domain-wide Delegation is set up, I need to control scenarios where the correct scopes are not allocated to the service account. Is there a way that a service account can see what scopes it has access to?
The only way I can think of currently is just to try certain API calls to see if they return 403 or not, but that seems like a waste of an API call. I know when using OAuth2, you can call https://www.googleapis.com/oauth2/v1/tokeninfo?access_token= to get the scopes, but I would need to know the customerID of the domain I am querying against. All of the API calls I plan on using will either be for a specific resource, or take a customerID parameter, so access could be different per domain.
If it's worth knowing, I am currently using the google-api-dotnet-client as it handles a lot of the authentication for me, but if this is easier to do in HTTPS calls then I'm happy to do that.
Update: Thought it might help to show an example of the code I am using to access the Google APIs, to show where I might run into issues. The code itself works fine, I am just trying to think about all possible scenarios where things could go wrong
string serviceAccountEmail = "";
string serviceAccountPrivateKey = "";
ServiceAccountCredential serviceCredential = new(new ServiceAccountCredential.Initializer(serviceAccountEmail)
{
Scopes = new[] {
DirectoryService.Scope.AdminDirectoryDeviceChromeosReadonly
},
User = "" // This would be different per Google account I am accessing
}.FromPrivateKey(serviceAccountPrivateKey));
DirectoryService service = new(new BaseClientService.Initializer()
{
HttpClientInitializer = serviceCredential
});
string customerId = ""; // This would be different per Google account I am accessing
// This could error if the DirectoryService.Scope.AdminDirectoryDeviceChromeosReadonly was not granted to the service account
var result = await services.Chromeosdevices.List(customerId).ExecuteAsync();
I got some of the APP's APIs.
When I use the browser to access these APIs, the browser popup window tell me to fill in the username/password, Then I tried to fill out my username/password and found that I passed the verification!
Then I tried to write the code
var myClientHandler = new HttpClientHandler();
myClientHandler.Credentials = new NetworkCredential("abc", "!##");
this._client = new HttpClient(myClientHandler);
this._client.BaseAddress = new Uri("http://api.xxx.com");
var result = await this._client.GetStringAsync("some_api_foo.json");
Run well!
(We know that if there are no NetworkCredential, there will be 401 unauthorized exception)
But I found out that the official APP could access some of the APIs without the user logging in. How does it work? Does it use a public account? Or is there another way to access the APIs?
It uses Windows integrated authentication (Kerberos) to authenticate your users without asking them for credentials
Use Fiddler >check Authorization Header is present: Basic xxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxx is Username:Password(Base64)
Decrypt it!
Coding in ASP.NET 4.0 / javascript/ jQuery/ WebServices
The Scenario
I have an analytics account i have set up at, say, some-name#gmail.com with password as pass123
I also know the table id,say ga:30037474
My question is can I pull data like
// Load the Google data JavaScript client library.
google.load('gdata', '2.x', { packages: ['analytics'] });
// Set the callback function when the library is ready.
google.setOnLoadCallback(init);
function init() {
myService = new google.gdata.analytics.AnalyticsService('charts_sample');
//how do i securely pull data without exposing my credentials if client login is a must
getDataFeed();
}
/**
* Main method to get report data from the Export API.
*/
function getDataFeed() {
myService = new google.gdata.analytics.AnalyticsService('charts_sample');
var myFeedUri = ['https://www.google.com/analytics/feeds/data',
'?start-date=2010-06-01',
'&end-date=2010-06-10',
'&dimensions=ga:day,ga:visitorType',
'&metrics=ga:visits',
'&sort=ga:day',
'&max-results=20',
'&ids=',
'ga:30037474'].join('');
myService.getDataFeed(myFeedUri, handleDataFeed, handleError);
}
Or shall i authenticate the client before this?
If I need to authenticate the client, it would be better if I get some pointers on how to proceed with these two requirements.
1. Cannot authenticate by exposing the user credentials on client side(Need a webservice like thing)
2. When my site loads, it should load up with the analytics data(should not ask for login then and there to pull the analytics data).
Are there any articles anywhere?
Not sure if this answers your question. Based on the content of your question it seems you have a very good handle on the Google Analytics API. But somewhere along the line someone will need to grant access to the Google Analytics data. Using AuthSub this can be accomplished. Basically the user will need to do a one-time login to Google Analytics and "grant" your webservice a long-lived token to access their data. Once this is done you can store this token and associate it with their account, passing it when making data calls to the Google Analytics API.
I have web service, which use integrated security in IIS.
Now, I want to test my web service.
I created a console application and adding web reference.
now, when i m trying to use web method. It show 401 error.
m i missing any authentication.
I think i need to pass user name and password programatically.
can anyone direct me in right direction.
Set the web service credentials to the System.Net.CredentialCache.DefaultCredentials in your console app
MyWebService proxy = new MyWebService();
proxy.Credentials = System.Net.CredentialCache.DefaultCredentials;
Edit
pass credentials programmatically:
MyWebService proxy = new MyWebService();
proxy.Credentials = new System.Net.NetworkCredential("username", "password", "domainname");
You need to add your windows id on your desktop to the allowed users in IIS.
I have a SOAP web service running on my sharepoint box under the _layouts directory, and a thick client which uses that SOAP service. We have one sharepoint box that uses basic auth and another which uses client certificates. I need that SOAP service to update some list items in a document library. The problem I'm having is nothing seems to work unless I run within an elevated privileges block. Here is a code snippet of what I'm trying to do.
using (SPSite site = new SPSite(fileUrl))
using (SPWeb web = site.OpenWeb()) {
// web.CurrentUser is always null unless in elevated privileges block.
// do something with document library...
web.Files.Add(...); // fails with access denied unless in elevated privileges block.
}
I also tried "SPContext.Current.Web" but it returns null for "web.CurrentUser" even if I'm in an elevated privileges block.
I really can't use an elevated privileges block because the users complain that anything my SOAP service touches has a modified by system.
From the thick client we are using code like the following...
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestString);
if(basicAuth) {
request.Credentials = System.Net.CredentialCache.DefaultCredentials;
}
else {
X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly);
foreach (X509Certificate2 certificate in store.Certificates) {
request.ClientCertificates.Add(certificate);
}
request.GetResponse();
We are manually constructing the SOAP request for various reasons.
If you want your webservice to properly integrate within the sharepoint context (i.e. being able to query the "current sharepoint user"), you should really deploy it to _vti_bin (the ISAPI subfolder of the 12 hyve), not to _layouts.
Discovery is a bit of a pain and requires manual tweaking of files (see the MSDN article on custom webservices within SharePoint for more information), but as you are hand-building your request anyway discovery should not be an issue.
[Edit] As an alternative, you can try acquiring the SPUserToken of the windows authenticated user,
SPUserToken token = web.AllUsers[WindowsIdentity.GetCurrent().Name].UserToken;
and then use this token to open the site and web as this user.