Service account is not authorized to manage project - c#

I recently joined a team, and am adding Android Management Api to the already existing project. I added the management API, created service accounts with permissions, and am writing the .NET project to test it out.
I made a service account with Android Management User and Owner permissions. However, when I try to use the .NET library to make an enterprise, I get
The service androidmanagement has thrown an exception. HttpStatusCode is Forbidden. Caller is not authorized to manage project.
If it helps:
The API key I'm using is allowed to call any API, and the application name is a temporary one that does NOT match the project name. As for the service account with private key, I am using a FileStream to read a .json file downloaded when the service account was created.
This is my code, based on the sample app https://developers.google.com/android/management/sample-app
The error gets thrown on the createRequst.Execute()
string CreateEnterprise()
{
SignupUrlsResource.CreateRequest signupUrlRequest = managementService.SignupUrls.Create();
signupUrlRequest.ProjectId = cloud_project_id;
signupUrlRequest.CallbackUrl = "https://www.yahoo.com";
var signupUrl = signupUrlRequest.Execute();
string enterpriseToken = signupUrl.Url;
Console.WriteLine("Signup: " + enterpriseToken);
EnterprisesResource.CreateRequest createRequest = managementService.Enterprises.Create(new Enterprise());
createRequest.ProjectId = "Test Project";
createRequest.SignupUrlName = signupUrl.Name;
createRequest.EnterpriseToken = enterpriseToken;
var enterprise = createRequest.Execute();
return enterprise.Name;
}

Turns out the createRequest.ProjectId must match the project name that has the Android Management API, aka the project I'm working with.

Related

Cross Account Access to DynamoDb tables C#

I have been dealing with this issue for which I am not able to find solution online anywhere.
I have a code which connects to AWS DynmoDb and performs read/write operations on one or more tables. This worked fine as long as my code and the DynamoDb table are in the same AWS account. Also the code uses the IAM Role attached to the Web Server. The role as all the necessary permissions assigned to it.
private AmazonDynamoDBClient GetDbClient(int ConnectionTimeOut, int ReadWriteTimeOut, int MaxRetry)
{
AmazonDynamoDBConfig clientConfig = new AmazonDynamoDBConfig
{
Timeout = TimeSpan.FromMilliseconds(ConnectionTimeOut),
ReadWriteTimeout = TimeSpan.FromMilliseconds(ReadWriteTimeOut),
MaxErrorRetry = MaxRetry
};
return new AmazonDynamoDBClient(clientConfig);
}
Recently I need to move my code to different AWS account and things started going crazy.
Following steps I have already taken.
VPC Peering done between the VPC in the old AWS account and the new AWS account.
Cross account permissions on the DynamobDb tables are given to the role which is used by the Web server on the new AWS Account.
With this change, I do not see any more permission errors but the code tries to look for the table on the new AWS account.
It is clear in the code that AWS AccountId is not used anywhere while creating AWS DynamoDb client. So I assume that I should be able to tell the code where to look for DynamoDb table. But the C# SDK of DynamoDb does not have any provision where I can provide AWS AccountId while creating DynamoDb client.
So my issue here is related to C# code to connect to DynamoDb service and not the IAM roles and permissions on AWS (for this I am able to fine plenty of solution).
Found this question aws cross account dynamodb access with IAM role with similar issue but it does not suggest the fix to do in the code.
One way to proceed is to use Security Token Service. First you need to assume a role and get temporary credentials:
Credentials GetCredentials(String roleArn)
{
using (var stsClient = new AmazonSecurityTokenServiceClient())
{
try
{
var response = stsClient.AssumeRole(new AssumeRoleRequest(roleARN));
if (response.HttpStatusCode == System.Net.HttpStatusCode.OK) return response.Credentials;
}
catch (AmazonSecurityTokenServiceException ex)
{
return null;
}
}
}
You can then use the credentials to initiate your DynamoDB client.
See another example here.
The AWS SDK and CLI (whether it's running locally or on (say) an EC2 instance) looks in the following locations for credentials:
Command line options
Environment variables
CLI credentials file
CLI configuration file
Container credentials
Instance profile credentials
If you have a credentials file configured, then, assuming we're running under the default profile, this will indirectly define the account under which it is running via the access key provided.
You can also define AWS-specific environment variables, such as AWS_ACCESS_KEY_ID which take precedence over the credentials file.
https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html

Firestore C#: Missing or insufficient permissions

I am currently exploring Firebase's Cloud Firestore in C# and has encountered with the error which I could not resolve after searching SO. It seems that the resources for Firestore in C# is quite limited:
"Status(StatusCode=PermissionDenied, Detail=\"Missing or insufficient permissions.\")"
My code so far:
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
Environment.SetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS", "FirebaseCsharpTest.json");
string project = "MyProjectId";
FirestoreDb db = FirestoreDb.Create(project);
Console.WriteLine("Created Cloud Firestore client with project ID: {0}", project);
AddPerson(db).GetAwaiter().GetResult();
}
public static async Task AddPerson(FirestoreDb db)
{
CollectionReference collection = db.Collection("users");
DocumentReference document = await collection.AddAsync(new
{
Name = new
{ First = "Ada", Last = "Lovelace" },
Born = 1815
});
}
}
I have checked on my Firebase console that the Firestore security rules are set to public (as of now, for testing sake). I have also ensured that the authentication json file is the right file generated from Google Developer Console as suggested in this post.
Is there something I'm missing?
EDIT:
My permissions on google cloud console:
Do check the projectID that you have been adding.
ProjectID is supposed to be the one that is specified in your json file.
This is a Cloud IAM issue and not a security rule issues. The C# server client library creates a privileged server environment that doesn't take into account Cloud Firestore security rules.. It seems that either your key file's service account doesn't have the correct IAM role or your code is not finding your keyfile.
Try using the full path to your keyfile instead of the relative path.
You can also try setting up a new service account and key file as described here.
Also, make sure you are changing the project variable:
string project = "NewFirebaseCsharpTest";
FirestoreDb db = FirestoreDb.Create(project);
Change the string project to the Id of the project and not the name of the project. The Id will probably start with the name and have a numeric suffix.
If that fails, go to the Log Explorer and query the logs. You will see an error that explains why your permission was denied.
You're never going to get enough information from the client-side for security reasons. Google isn't going to tell someone trying to gain access to something they shouldn't have access to what is going wrong. But, an admin can view the logs on the other side which will log all the information.

Sharepoint CSOM Authentication issue with .NET Core

I'm new to Sharepoint online, and don't have an own account (yet), just an username/password from a client.
Need to build a service that gets the folder structure and archives from Sharepoint. And then allows to up/download archives.
Since the package
Microsoft.SharePointOnline.CSOM
is not compatible with .NET Core, I'm using this github solution that seems to cover the main functionality in an equal way: https://github.com/OneBitSoftware/NetCore.CSOM
I think there is nothing wrong with that so far - but when trying to connect using
SharePointOnlineCredentials
...I'm getting the error
PPCRL_REQUEST_E_PARTNER_HAS_NO_ASYMMETRIC_KEY
So I guess there's some account setting missing on the server side? Or am I following a wrong approach? I would have no problem implementing an OAuth access to get a Bearer token, but which API would that be, and how can I register an app for Sharepoint?
My research about API's and this particular error didn't result in anything yet, so I'm reaching out for help here.
Get NuGet package TTCUE.NetCore.SharepointOnline.CSOM.16.1.8029.1200.
You can also download an official package Microsoft.SharePointOnline.CSOM but it will attach wrong dlls to your project and you would need to change them according to the link from a different answer here - https://rajujoseph.com/getting-net-core-and-sharepoint-csom-play-nice/
Note - Your .NET Core project will compile, but it doesn't mean that it will work on, for example, linux. Those CSOM dlls are not finished and Microsoft is still working on them.(for a loooong time...)
Check the example below:
Create a .NET Core console app.
Add the references: Microsoft.SharePoint.Client.Portable.dll, Microsoft.SharePoint.Client.Runtime.Portable.dll, and Microsoft.SharePoint.Client.Runtime.Windows.dll.
Note: If the project has references to Microsoft.SharePoint.Client.dll and Microsoft.SharePoint.Client.Runtime.dll, please remove them.
These references can be accessed by installing CSOM library into another project, and then navigating to installed nuget packages in the file directory:
c:\Users\user\\.nuget\packages\microsoft.sharepointonline.csom\\(version)\lib\netcore45
Add the code below to the .NET Core 2.0 console application:
using System;
using Microsoft.SharePoint.Client;
namespace ConsoleApp1 {
class Program {
static void Main(string[] args) {
string targetSiteURL = #"https://xxx.sharepoint.com/sites/xxx";
var login = "xxx#xx.onmicrosoft.com";
var password = "xxx";
SharePointOnlineCredentials onlineCredentials = new SharePointOnlineCredentials(login, password);
ClientContext ctx = new ClientContext(targetSiteURL);
ctx.Credentials = onlineCredentials;
WebCreationInformation wci = new WebCreationInformation();
wci.Url = "Site1"; // This url is relative to the url provided in the context
wci.Title = "Site 1";
wci.UseSamePermissionsAsParentSite = true;
wci.WebTemplate = "STS#0";
wci.Language = 1033;
var newWeb = ctx.Web.Webs.Add(wci);
ctx.Load(newWeb, w => w.Title);
ctx.ExecuteQueryAsync();
Console.WriteLine("Web title:" + newWeb.Title);
Console.ReadKey();
}
}
}
More information: Getting .NET Core and SharePoint CSOM Play Nice

Accessing Google Cloud Datastore locally from ASP.NET throws Grpc.Core.RpcException: "Missing or insufficient permissions."

I'm following the Using Cloud Datastore with .NET tutorial. At some point it says that you can run the provided project locally by just pressing F5. When I do that I get the following exception
Grpc.Core.RpcException: 'Status(StatusCode=PermissionDenied, Detail="Missing or insufficient permissions.")'
This exception is thrown exactly at the _db.RunQuery(query) line.
var query = new Query("Book") { Limit = pageSize };
if (!string.IsNullOrWhiteSpace(nextPageToken))
query.StartCursor = ByteString.FromBase64(nextPageToken);
var results = _db.RunQuery(query);`
If I deploy the application to cloud it works as expected, no error. I've given datastore owner permissions to all accounts in Cloud IAM (Identity and Access Management) but it still doesn't work. Does anybody have any ideas?
As Jon Skeet pointed out, I was using the wrong json key locally. Previously I created a compute engine that has a separate service account. After I downloaded a new json key from Console -> IAM & Admin -> Service Accounts it worked locally as well.

Can't access public folders root

I've recently coded a .NET Console app using C#. It's purpose was to read the emails within a specific folder, parse them for specific values and save them to a database.
Our email system, at the time I originally coded this, was Exchange 2003. However, I was made aware we would soon be upgrading to Exchange 2010: ergo, I built the code to work in both environments.
Following the migration to Exchange 2010, however, the app has broken.
The app uses the EWS API for 2010 functionality. When it attempts to use the ExchangeService's FindFolders method to find the publicfoldersroot, it throws an exception. Here's the code:
ExchangeService service = new ExchangeService();
FindFoldersResults findRootFldrs;
service.UseDefaultCredentials = true;
service.AutodiscoverUrl("xxxxx#xxxx.xxx", delegate(string x) {
return true; });
FolderView fview = new FolderView(100);
fview.Traversal = FolderTraversal.Deep;
findRootFldrs = service.FindFolders(WellKnownFolderName.PublicFoldersRoot,
fview);
The exception: ErrorInvalidSchemaVersionForMailboxVersion, aka:
The mailbox that was requested doesn't support the specified RequestServerVersion
I've attempted:
Setting the exchangeservice to 2007 (throws an exception: "An internal server error occurred. The operation failed.")
Giving myself the highest level of permission to the Public Folder (no effect)
Manually setting my credentials (no effect)
I can view the public folders in Outlook 2007; the publicfoldersroot property is available in the intellisense; the code works on local folders (I can parse my inbox).
My current thinking is that it's a setting on the recent setup of Exchange 2010: unfortunately that isn't really my field. The exception tells me it's trying to use a previous version of Exchange. Setting it to 2007 simply causes the code to fail with an internal server error.
Old post, but this turned out to be the answer for me: http://technet.microsoft.com/en-us/library/bb629522.aspx
Essentially the account used to connect with EWS had a mailbox in a mailbox database whose default public folder server was still Exchange 2003. Any and all attempts to enumerate public folders over EWS failed. Swapping it out for a 2010 backend server cured it instantly.
Have you tried esb.RequestServerVersion.Version = ExchangeVersionType. Exchange2010 (or SP1)
Change this line:
ExchangeService service = new ExchangeService();
to something like this:
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010);
or
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010_SP1);
Depending on your version.

Categories