Can't get SharePoint access token - c#

I have created an app in SharePoint 2013, using AppRegNew.aspx, from where I got an app secrete and id. For this app I set permissions of reading and writing to Documents list, using AppInv.aspx.
Now, I want to use the app secrete and Id from another project to access the documents list. I am using TokenHelper class like below:
TokenHelper.GetAppOnlyAccessToken(TokenHelper.SharePointPrincipal, siteUri.Authority, realm).AccessToken
But I get an exception:
The remote server returned an error: (404) Not Found. - The requested namespace does not exist.
I debugged the code from TokeHelper class and found that the exception comes from this web call:
https://accounts.accesscontrol.windows.net/metadata/json/1?realm=my_realm_value
which is located in method:
private static JsonMetadataDocument GetMetadataDocument(string realm)
Any help will be appreciated, thank you :-)

In the end I managed to figure it out. I used a SharePoint app that had the following permissions:
<AppPermissionRequests AllowAppOnlyPolicy="true">
<AppPermissionRequest Scope="http://sharepoint/content/sitecollection/web/list" Right="Write">
<Property Name="BaseTemplateId" Value="101"/>
</AppPermissionRequest>
</AppPermissionRequests>
Beside this I used a certificate in order to get the access token. That certificate I linked with the app and set it as a trust token issuer using a PowerShell script:
$issuerID = [System.Guid]::NewGuid().ToString().ToLower()
$publicCertPath = "your_cer_file.cer"
$certificate = Get-PfxCertificate $publicCertPath
$web = Get-SPWeb "http://your.sharepoint.url/"
$realm = Get-SPAuthenticationRealm -ServiceContext $web.Site
$fullAppIdentifier = $issuerId + '#' + $realm
New-SPTrustedSecurityTokenIssuer -Name "High Trust App" -Certificate $certificate - RegisteredIssuerName $fullAppIdentifier -IsTrustBroker
$issuerID
iisreset
Then I used TokenHelper class like this:
var siteUri = new Uri("my_site_url");
TokenHelper.GetS2SAccessTokenWithWindowsIdentity(siteUri, null);

Related

Facing Issues while retrieving token for local development in c# via Azure.Identity

I am developing a azure function which needs to connect to Microsoft Dataverse via managed Identity. During local development I have added my azure account in visual studio and selected for azure function authentication. I'm using the below code to access token :
var vsCred = new VisualStudioCredential();
var tok = await vsCred.GetTokenAsync(
new TokenRequestContext(new[] { "CLIENT ID of managed identity" }),default
);
But getting this error :
System.Private.CoreLib: Exception while executing function: ManagedIdentityTestFxn. System.Private.CoreLib: Process "C:\Program Files\Microsoft Visual Studio\2022\Professional\Common7\IDE\CommonExtensions\Microsoft\Asal\TokenService\Microsoft.Asal.TokenService.exe" has failed with unexpected error: TS003: Error, TS004: Unable to get access token. 'AADSTS65001: The user or administrator has not consented to use the application with ID '' named 'VS with native MSA'. Send an interactive authorization request for this user and resource.
Azure AD Permissions :
enter image description here
enter image description here
I tried giving admin consent but still facing the same issue.
enter image description here
enter image description here
Instead of using VisualStudioCredential you can use this DefaultAzureCredential to get access an token like below:
using Azure.Core;
using Azure.Identity;
string userAssignedClientId = "<your managed identity client Id>";
var credential = new DefaultAzureCredential(new DefaultAzureCredentialOptions { ManagedIdentityClientId = userAssignedClientId });
var accessToken = credential.GetToken(new TokenRequestContext(new[] { "https://vault.azure.net" }));
// To print the token, you can convert it to string
String accessTokenString = accessToken.Token.ToString();
//You can use the credential object directly with Key Vault client.
var client = new SecretClient(new Uri("https://myvault.vault.azure.net)",credential);
Alternatively, you can run the below PowerShell script In the kudo console of your function app like below
$resourceURI ="https://admin.services.crm.dynamics.com"
$client_id = "dd8770dc-cbae-43f0-a36d-e27XXXXX"
$tokenAuthURI = $env:IDENTITY_ENDPOINT + "?resource=$resourceURI&client_id=$client_id&api-version=2019-08-01"
$tokenResponse = Invoke-RestMethod -Method Get -Headers #{"X-IDENTITY-HEADER"="$env:IDENTITY_HEADER"} -Uri $tokenAuthURI
$accessToken = $tokenResponse.access_token
I tried to reproduce the same in my environment with powershell script and got the results like below:
I have a function app where I added managed identity like this:
Go to kudo console in function app, Now open kudo console by selecting the advancedtool in your function App :
Now I selected powershell and ran the script like below:
$resourceURI ="https://admin.services.crm.dynamics.com"
$client_id = "dd8770dc-cbae-43f0-a36d-e27XXXXX"
$tokenAuthURI = $env:IDENTITY_ENDPOINT + "?resource=$resourceURI&client_id=$client_id&api-version=2019-08-01"
$tokenResponse = Invoke-RestMethod -Method Get -Headers #{"X-IDENTITY-HEADER"="$env:IDENTITY_HEADER"} -Uri $tokenAuthURI
$accessToken = $tokenResponse.access_token
When I ran the $accessToken I got the token successfully like below:
Reference:
Use managed identities on a virtual machine to acquire access token - Azure AD - Microsoft Entra | Microsoft Learn

SharePoint 2013: Why getting 500 error while creating clientContext?

I want to create a IIS webservice which has to write list items to SharePoint on Premise.
I want to use CSOM and try to create a ClientContext.
public string AddListItem()
string result = string.Empty;
string siteUrl = "https://serverUrl";
using (ClientContext context = new ClientContext(siteUrl))
{
context.Credentials = new NetworkCredential("User", "Password", "Domain");
List list = context.Web.Lists.GetByTitle("Test");
context.Load(list);
context.ExecuteQuery();
}
return result;
}
While executing, I get an error at context.ExecuteQuery();
System.Net.WebException: 'The remote server returned an error: (500) Internal Server Error.'
In the Event Log, I see following error:
WebHost failed to process a request.
Sender Information: System.ServiceModel.ServiceHostingEnvironment+HostingManager/41028758
Exception: System.ServiceModel.ServiceActivationException: The service '/_vti_bin/client.svc' cannot be activated due to an exception during compilation. The exception message is: Operation is not valid due to the current state of the object.. ---> System.InvalidOperationException: Operation is not valid due to the current state of the object.
at Microsoft.SharePoint.Administration.SPWebApplication.get_Context()
................................
In debugging, I also see after creating the ClientContext and before context.ExecuteQuery(); following error at some properties of ClientContext, e.g.:
ServerLibraryVersion = 'context.ServerLibraryVersion' threw an exception of type 'Microsoft.SharePoint.Client.PropertyOrFieldNotInitializedException'
Your code seems fine for on-prem SharePoint. I think You should check some settings on the farm that my be the cause of that.
Please check the services on farm server if the IIS Admin Service is on
also on SharePoint CA check the user profile service and the claims to windows token service (both should be on)
... sorry for the lang :)... usually I have access to SharePoint in PL language, but I tried to translate the most important stuff to ang.
Please also check if on IIS the app pools that You try to access are working correctly. I suppose yes, otherwise You would have a lot of other errors, but it's always better to check.
Use CSOM, what to use WCF is not clear:
ClientContextctx = newClientContext("http://gowtham.sharepoint.com");
List oList = ctx.Web.Lists.GetByTitle("Announcements");
ListItemCreationInformationitemCreateInfo = newListItemCreationInformation();
ListItemnewItem = oList.AddItem(itemCreateInfo);
newItem["Title"] = "Test Item!";
newItem["Body"] = "welcome to Gowtham Blog";
newItem.Update();
context.ExecuteQuery();
Try below code
using (ClientContext clientContext = new ClientContext(ServerURL))
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
var securePassword = new SecureString();
foreach (char c in password)
{
securePassword.AppendChar(c);
}
clientContext.Credentials = new SharePointOnlineCredentials(your_mail_ID, securePassword);
Web web = clientContext.Web;
var list = web.Lists.GetByTitle("your_list_name");
clientContext.Load(list.RootFolder);
clientContext.ExecuteQuery();
}
Check if the "SharePoint Web Servies Root" application pool was stopped or the "SharePoint Web Services" web application not start in IIS.
Go to IIS Application Pools, find the "SecurityTokenServiceApplicationPool" and click "Advanced Settings" from the action panel, then Scroll to "ProcessModel" section and change the Identity to your SharePoint Farm Account and do IISRESET.
And create a console application with the CSOM C# code to check if it works.
FWIW - I had exactly the same error - CSOM local mode to on-prem SP2016 with a 500 error requesting the list by title.
I had just applied a 10/2019 SharePoint update, but hadn't gone through Product Configuration Wizard and the prompts in Central Admin. Once I did that, CSOM requests worked again.

How to connect xamarin android app to Cloud Firestore db

I have tried many ways as in several sites but no luck, I tried to connect it using Google.Cloud.Firestore and Google.Apis.Storage.v1 Nuget packages. The code is given below.
Google.Cloud.Firestore.FirestoreDb db = Google.Cloud.Firestore.FirestoreDb.Create("test");
CollectionReference collection = db.Collection("users");
DocumentReference document = await collection.AddAsync(new { email = "xamemail#12", name = "xamemail" });
When I tried this code one exception occurred like environment variable GOOGLE_APPLICATION_CREDENTIALS not set, then I set GOOGLE_APPLICATION_CREDENTIALS in my windows system as well as in the code as shown below.
System.Environment.SetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS", #"C:\\path-to-json", EnvironmentVariableTarget.Machine);
It's showing another error the file is not found in the path, but its there and I set the permission for the path.
If anyone there to help on this, anyone already using a xamarin - cloud firestore db in your projects?
Please note its not the firebase realtime db, I am able to connect that.
As far I have understood, you can’t use default credentials (GOOGLE_APPLICATION_CREDENTIALS) in an app on a device as it would not be able to find the path for the file located on your PC.
I have found this code, that I think should work, (But so far, I have not managed to succeed with it - I get an exeption, so I hope my answer can help to inspire someone else to find a solution for this)
using Google.Cloud.Firestore;
using Google.Cloud.Firestore.V1;
using Google.Apis.Auth.OAuth2;
using Grpc.Auth;
using Grpc.Core;
...
//First Pack your Jason fil into a Jason string.
//Fore security reasons I'm not sure this is a good idea, but it is what I could think of
string jsonCred = #”{ Your Json cred file (Replace “ with ‘) }”;
// Get you credential. As far as I have understood it must be scoped.
var credential = GoogleCredential.FromJson(jsonCred).CreateScoped(FirestoreClient.DefaultScopes);
// Create a channel and add the channel to the Firestore client
Channel channel = new Channel(FirestoreClient.DefaultEndpoint.Host, FirestoreClient.DefaultEndpoint.Port, credential.ToChannelCredentials());
FirestoreClient client = FirestoreClient.Create(channel);
// Then I think it should be possible to call.
FirestoreDb db = FirestoreDb.Create(projectId, client);
But so far, I in the line:
FirestoreClient client = FirestoreClient.Create(channel):
I get this exception:
System.TypeLoadException: VTable setup of type Google.Cloud.Firestore.V1.FirestoreClientImpl failed at Google.Cloud.Firestore.V1.FirestoreClient.Create (Grpc.Core.Channel channel, Google.Cloud.Firestore.V1.FirestoreSettings settings) [0x0000c] in T:\src\github\google-cloud-dotnet\releasebuild\apis\Google.Cloud.Firestore.V1\Google.Cloud.Firestore.V1\FirestoreClient.cs:622 at Padlelogg.DataHandler.SaveToFireStore[T] (System.String collection, System.Collections.Generic.List`1[T] Datalist) [0x00072] in C:\Users\rad\Documents\Xamarin projects\Padlelogg 2.10\Padlelogg\Data\DataHandler.cs:360 }
This exception I have not been able to resolve so far

LDAP search fails on server, not in Visual Studio

I'm creating a service to search for users in LDAP. This should be fairly straightforward and probably done a thousand times, but I cannot seem to break through properly. I thought I had it, but then I deployed this to IIS and it all fell apart.
The following is setup as environment variables:
ldapController
ldapPort
adminUsername 🡒 Definitely a different user than the error reports
adminPassword
baseDn
And read in through my Startup.Configure method.
EDIT I know they are available to IIS, because I returned them in a REST endpoint.
This is my code:
// Connect to LDAP
LdapConnection conn = new LdapConnection();
conn.Connect(ldapController, ldapPort);
conn.Bind(adminUsername, adminPassword);
// Run search
LdapSearchResults lsc = conn.Search(
baseDn,
LdapConnection.SCOPE_SUB,
lFilter,
new string[] { /* lots of attributes to fetch */ },
false
);
// List out entries
var entries = new List<UserDto>();
while (lsc.hasMore() && entries.Count < 10) {
LdapEntry ent = lsc.next(); // <--- THIS FAILS!
// ...
}
return entries;
As I said, when debugging this in visual studio, it all works fine. When deployed to IIS, the error is;
Login failed for user 'DOMAIN\IIS_SERVER$'
Why? The user specified in adminUsername should be the user used to login (through conn.Bind(adminUsername, adminPassword);), right? So why does it explode stating that the IIS user is the one doing the login?
EDIT I'm using Novell.Directory.Ldap.NETStandard
EDIT The 'user' specified in the error above, is actually NOT a user at all. It is the AD registered name of the computer running IIS... If that makes any difference at all.
UPDATE After consulting with colleagues, I set up a new application pool on IIS, and tried to run the application as a specified user instead of the default passthrough. Exactly the same error message regardless of which user I set.
Try going via Network credentials that allows you to specify domain:
var networkCredential = new NetworkCredential(userName, password, domain);
conn.Bind(networkCredential);
If that does not work, specify auth type basic (not sure that the default is) before the call to bind.
conn.AuthType = AuthType.Basic;

TF400813: Resource not available for anonymous access. Client authentication required

I am working on the CodedUI Test Automation project. i am developing a framework in which i am trying to access Test Cases in VSTS through RestAPI. I have worked on an MVC application previously in which i did the same thing to pull data from VSTS using RestAPI.
Now the problem is i am not able to access the VSTS. Everytime i am trying to access the VSTS, i got the exception TF400813: Resource not available for anonymous access. Client authentication required.
I am using the same PAT token. I have all the required access on my team project. I am able to access all work items in my project from browser. I have tried all the option mentioned in below thread but still its not working.
Client authentication error when starting Visual Studio 2015.3Any leads will be appreciated.Below is my code to get data from VSTS:
public static List<WorkItem> GetWorkItemsWithSpecificFields(IEnumerable<int> ids)
{
var collectionUri = "https://<name>.visualstudio.com";
var fields = new string[] {
"System.Id",
"System.Title",
"System.WorkItemType",
"Microsoft.VSTS.Scheduling.RemainingWork"
};
using (WorkItemTrackingHttpClient workItemTrackingHttpClient = new WorkItemTrackingHttpClient(new Uri(collectionUri), new VssBasicCredential("", System.Configuration.ConfigurationManager.AppSettings["PATToken"])))
{
// Exception is coming on below line
List<WorkItem> results = workItemTrackingHttpClient.GetWorkItemsAsync(ids, fields).Result;
return results;
}
}

Categories